/*
 *  In P51-02 someone mentioned Ethernet spoofing.  Here you go.
 *  This tiny program can be used to trick some smart / switching hubs.
 *
 *  AWL production: (General Public License v2)
 *
 *      changemac  version 1.0  (2.20.1998)
 *
 *  changemac  --   change MAC address of your ethernet card.
 *
 *  changemac [-l] | [-d number ] [ -r | -a address ]
 *
 *      -d number       number of ethernet device, 0 for eth0, 1 for eth1 ...
 *                      if -d option is not specify default value is 0 (eth0)
 *
 *      -h              help for changemac command
 *
 *      -a address      address format is xx:xx:xx:xx:xx:xx
 *
 *      -r              set random MAC address for ethernet card
 *
 *      -l              list first three MAC bytes of known ethernet vendors
 *                      (this list is not compleet, anyone who know some more
 *                      information about MAC addresses can mail me)
 *
 *  changemac does not change hardware address, it just change data in
 *  structure of kernel driver for your card.  Next boot on your computer will
 *  read real MAC form your hardware.
 *
 *  The changed MAC stays as long as your box is running, (or as long as next
 *  successful changemac).
 *
 *  It will not work if kernel is already using that ethernet device.  In that
 *  case you have to turn off that device (ifconfig eth0 down).
 *
 *  I use changemac in /etc/rc.d/rc.inet1 (slackware, or redhat) just line
 *  before ifconfig for ethernet device (/sbin/ifconfig eth0 ...)
 *
 *  The author will be very pleased if you can learn something form this code.
 *
 *  Updates of this code can be found on:
 *  http://galeb.etf.bg.ac.yu/~azdaja/changemac.html
 *
 *  Sugestions and comments can be sent to author:
 *  Milos Prodanovic <azdaja@galeb.etf.bg.ac.yu>
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <unistd.h>

struct LIST
{
    char name[50];
    u_char mac[3];
};

/*
 *  This list was obtainted from vyncke@csl.sni.be, created on 01.7.93.
 */

struct LIST vendors[] = {
                {"OS/9 Network                         ",'\x00','\x00','\x00'},
                {"BBN                                  ",'\x00','\x00','\x02'},
                {"Cisco                                ",'\x00','\x00','\x0C'},
                {"Fujitsu                              ",'\x00','\x00','\x0E'},
                {"NeXT                                 ",'\x00','\x00','\x0F'},
                {"Sytek/Hughes LAN Systems             ",'\x00','\x00','\x10'},
                {"Tektronics                           ",'\x00','\x00','\x11'},
                {"Datapoint                            ",'\x00','\x00','\x15'},
                {"Webster                              ",'\x00','\x00','\x18'},
                {"AMD ?                                ",'\x00','\x00','\x1A'},
                {"Novell/Eagle Technology              ",'\x00','\x00','\x1B'},
                {"Cabletron                            ",'\x00','\x00','\x1D'},
                {"Data Industrier AB                   ",'\x00','\x00','\x20'},
                {"SC&C                                 ",'\x00','\x00','\x21'},
                {"Visual Technology                    ",'\x00','\x00','\x22'},
                {"ABB                                  ",'\x00','\x00','\x23'},
                {"IMC                                  ",'\x00','\x00','\x29'},
                {"TRW                                  ",'\x00','\x00','\x2A'},
                {"Auspex                               ",'\x00','\x00','\x3C'},
                {"ATT                                  ",'\x00','\x00','\x3D'},
                {"Castelle                             ",'\x00','\x00','\x44'},
                {"Bunker Ramo                          ",'\x00','\x00','\x46'},
                {"Apricot                              ",'\x00','\x00','\x49'},
                {"APT                                  ",'\x00','\x00','\x4B'},
                {"Logicraft                            ",'\x00','\x00','\x4F'},
                {"Hob Electronic                       ",'\x00','\x00','\x51'},
                {"ODS                                  ",'\x00','\x00','\x52'},
                {"AT&T                                 ",'\x00','\x00','\x55'},
                {"SK/Xerox                             ",'\x00','\x00','\x5A'},
                {"RCE                                  ",'\x00','\x00','\x5D'},
                {"IANA                                 ",'\x00','\x00','\x5E'},
                {"Gateway                              ",'\x00','\x00','\x61'},
                {"Honeywell                            ",'\x00','\x00','\x62'},
                {"Network General                      ",'\x00','\x00','\x65'},
                {"Silicon Graphics                     ",'\x00','\x00','\x69'},
                {"MIPS                                 ",'\x00','\x00','\x6B'},
                {"Madge                                ",'\x00','\x00','\x6F'},
                {"Artisoft                             ",'\x00','\x00','\x6E'},
                {"MIPS/Interphase                      ",'\x00','\x00','\x77'},
                {"Labtam                               ",'\x00','\x00','\x78'},
                {"Ardent                               ",'\x00','\x00','\x7A'},
                {"Research Machines                    ",'\x00','\x00','\x7B'},
                {"Cray Research/Harris                 ",'\x00','\x00','\x7D'},
                {"Linotronic                           ",'\x00','\x00','\x7F'},
                {"Dowty Network Services               ",'\x00','\x00','\x80'},
                {"Synoptics                            ",'\x00','\x00','\x81'},
                {"Aquila                               ",'\x00','\x00','\x84'},
                {"Gateway                              ",'\x00','\x00','\x86'},
                {"Cayman Systems                       ",'\x00','\x00','\x89'},
                {"Datahouse Information Systems        ",'\x00','\x00','\x8A'},
                {"Jupiter ? Solbourne                  ",'\x00','\x00','\x8E'},
                {"Proteon                              ",'\x00','\x00','\x93'},
                {"Asante                               ",'\x00','\x00','\x94'},
                {"Sony/Tektronics                      ",'\x00','\x00','\x95'},
                {"Epoch                                ",'\x00','\x00','\x97'},
                {"CrossCom                             ",'\x00','\x00','\x98'},
                {"Ameristar Technology                 ",'\x00','\x00','\x9F'},
                {"Sanyo Electronics                    ",'\x00','\x00','\xA0'},
                {"Wellfleet                            ",'\x00','\x00','\xA2'},
                {"NAT                                  ",'\x00','\x00','\xA3'},
                {"Acorn                                ",'\x00','\x00','\xA4'},
                {"Compatible Systems Corporation       ",'\x00','\x00','\xA5'},
                {"Network General                      ",'\x00','\x00','\xA6'},
                {"NCD                                  ",'\x00','\x00','\xA7'},
                {"Stratus                              ",'\x00','\x00','\xA8'},
                {"Network Systems                      ",'\x00','\x00','\xA9'},
                {"Xerox                                ",'\x00','\x00','\xAA'},
                {"Western Digital/SMC                  ",'\x00','\x00','\xC0'},
                {"Eon Systems (HP)                     ",'\x00','\x00','\xC6'},
                {"Altos                                ",'\x00','\x00','\xC8'},
                {"Emulex                               ",'\x00','\x00','\xC9'},
                {"Darthmouth College                   ",'\x00','\x00','\xD7'},
                {"3Com ? Novell ? [PS/2]               ",'\x00','\x00','\xD8'},
                {"Gould                                ",'\x00','\x00','\xDD'},
                {"Unigraph                             ",'\x00','\x00','\xDE'},
                {"Acer Counterpoint                    ",'\x00','\x00','\xE2'},
                {"Atlantec                             ",'\x00','\x00','\xEF'},
                {"High Level Hardware (Orion, UK)      ",'\x00','\x00','\xFD'},
                {"BBN                                  ",'\x00','\x01','\x02'},
                {"Kabel                                ",'\x00','\x17','\x00'},
                {"Xylogics, Inc.-Annex terminal servers",'\x00','\x08','\x2D'},
                {"Frontier Software Development        ",'\x00','\x08','\x8C'},
                {"Intel                                ",'\x00','\xAA','\x00'},
                {"Ungermann-Bass                       ",'\x00','\xDD','\x00'},
                {"Ungermann-Bass                       ",'\x00','\xDD','\x01'},
                {"MICOM/Interlan [Unibus, Qbus, Apollo]",'\x02','\x07','\x01'},
                {"Satelcom MegaPac                     ",'\x02','\x60','\x86'},
                {"3Com [IBM PC, Imagen, Valid, Cisco]  ",'\x02','\x60','\x8C'},
                {"CMC [Masscomp, SGI, Prime EXL]       ",'\x02','\xCF','\x1F'},
                {"3Com (ex Bridge)                     ",'\x08','\x00','\x02'},
                {"Symbolics                            ",'\x08','\x00','\x05'},
                {"Siemens Nixdorf                      ",'\x08','\x00','\x06'},
                {"Apple                                ",'\x08','\x00','\x07'},
                {"HP                                   ",'\x08','\x00','\x09'},
                {"Nestar Systems                       ",'\x08','\x00','\x0A'},
                {"Unisys                               ",'\x08','\x00','\x0B'},
                {"AT&T                                 ",'\x08','\x00','\x10'},
                {"Tektronics                           ",'\x08','\x00','\x11'},
                {"Excelan                              ",'\x08','\x00','\x14'},
                {"NSC                                  ",'\x08','\x00','\x17'},
                {"Data General                         ",'\x08','\x00','\x1A'},
                {"Data General                         ",'\x08','\x00','\x1B'},
                {"Apollo                               ",'\x08','\x00','\x1E'},
                {"Sun                                  ",'\x08','\x00','\x20'},
                {"Norsk Data                           ",'\x08','\x00','\x26'},
                {"DEC                                  ",'\x08','\x00','\x2B'},
                {"Bull                                 ",'\x08','\x00','\x38'},
                {"Spider                               ",'\x08','\x00','\x39'},
                {"Sony                                 ",'\x08','\x00','\x46'},
                {"BICC                                 ",'\x08','\x00','\x4E'},
                {"IBM                                  ",'\x08','\x00','\x5A'},
                {"Silicon Graphics                     ",'\x08','\x00','\x69'},
                {"Excelan                              ",'\x08','\x00','\x6E'},
                {"Vitalink                             ",'\x08','\x00','\x7C'},
                {"XIOS                                 ",'\x08','\x00','\x80'},
                {"Imagen                               ",'\x80','\x00','\x86'},
                {"Xyplex                               ",'\x80','\x00','\x87'},
                {"Kinetics                             ",'\x80','\x00','\x89'},
                {"Pyramid                              ",'\x80','\x00','\x8B'},
                {"Retix                                ",'\x80','\x00','\x90'},
                {'\x0','\x0','\x0','\x0'}
                     };

void change_MAC(u_char *,int);
void list();
void random_mac(u_char *);
void help();
void addr_scan(char *,u_char *);

int
main(int argc, char ** argv)
{
    char c;
    u_char mac[6] = "\0\0\0\0\0\0";
    int nr = 0,eth_num = 0,nr2 = 0;
    extern char *optarg;

    if (argc == 1)
    {
        printf("for help: changemac -h\n");
        exit(1);
    }

    while ((c = getopt(argc, argv, "-la:rd:")) != EOF)
    {
        switch(c)
        {
            case 'l' :
                list();
                exit(1);
            case 'r' :
                nr++;
                random_mac(mac);
                break;
            case 'a' :
                nr++;
                addr_scan(optarg,mac);
                break;
            case 'd' :
                nr2++;
                eth_num = atoi(optarg);
                break;
            default:
                help();
                exit(1);
        }
        if (nr2 > 1 || nr > 1)
        {
            printf("too many options\n");
            exit(1);
        }
    }
    change_MAC(mac,eth_num);
    return (0);
}

void
change_MAC(u_char *p, int ether)
{
    struct  ifreq  devea;
    int s, i;

    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0)
    {
        perror("socket");
        exit(1);
    }

    sprintf(devea.ifr_name, "eth%d", ether);
    if (ioctl(s, SIOCGIFHWADDR, &devea) < 0)
    {
        perror(devea.ifr_name);
        exit(1);
    }

    printf("Current MAC is\t");
    for (i = 0; i < 6; i++)
    {
        printf("%2.2x ", i[devea.ifr_hwaddr.sa_data] & 0xff);
    }
    printf("\n");

/* an ANSI C  ?? --> just testing your compiler */
    for(i = 0; i < 6; i++) i[devea.ifr_hwaddr.sa_data] = i[p];

    printf("Changing MAC to\t");

/* right here i am showing how interesting is programing in C */

    printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
        0[p],
        1[p],
        2[p],
        3[p],
        4[p],
        5[p]);

    if (ioctl(s,SIOCSIFHWADDR,&devea) < 0)
    {
        printf("Unable to change MAC -- Is eth%d device is up?\n", ether);
        perror(devea.ifr_name);
        exit(1);
    }
    printf("MAC changed\n");

    /* just to be sure ... */

    if (ioctl(s, SIOCGIFHWADDR, &devea) < 0)
    {
        perror(devea.ifr_name);
        exit(1);
    }

    printf("Current MAC is: ");

    for (i = 0; i < 6; i++) printf("%X ", i[devea.ifr_hwaddr.sa_data] & 0xff);
    printf("\n");

    close(s);
}

void
list()
{
    int i = 0;
    struct LIST *ptr;

    printf("\nNumber\t MAC addr \t vendor\n");
    while (0[i[vendors].name])
    {
        ptr = vendors + i;
        printf("%d\t=> %2.2x:%2.2x:%2.2x \t%s \n",
            i++,
            0[ptr->mac],
            1[ptr->mac],
            2[ptr->mac],
            ptr->name);
        if (!(i % 15))
        {
            printf("\n press enter to continue\n");
            getchar();
        }
    }
}

void
random_mac(u_char *p)
{
    srandom(getpid());

    0[p] = random() % 256;
    1[p] = random() % 256;
    2[p] = random() % 256;
    3[p] = random() % 256;
    4[p] = random() % 256;
    5[p] = random() % 256;
}

void
addr_scan(char *arg, u_char *mac)
{
    int i;

    if (!(2[arg] == ':' &&
            5[arg] == ':' &&
            8[arg] == ':' &&
            11[arg] == ':' &&
            14[arg] == ':' &&
            strlen(arg) == 17 ))
    {
        printf("address is not in spacified format\n");
        exit(0);
    }
    for(i = 0; i < 6; i++) i[mac] = (char)(strtoul(arg + i*3, 0, 16) & 0xff);
}

void
help()
{
    printf(" changemac - soft change MAC address of your ethernet card \n");
    printf(" changemac -l | [-d number ] [ -r | -a address ] \n");
    printf("   before you try to use it just turn ethernet card off, ifconfig ethX down\n");
    printf(" -d number    number of ethernet device \n");
    printf(" -h           this help \n");
    printf(" -a address   address format is xx:xx:xx:xx:xx:xx \n");
    printf(" -r           set random generated address \n");
    printf(" -l           list first three MAC bytes of known ethernet vendors\n");
    printf(" example: changemac -d 1 -a 12:34:56:78:9a:bc\n");
}

/* EOF */

---------------------------------------------------------------------------
 1998 Rootshell - Unauthorized duplication prohibited.
