Go Down

Topic: MAC address randomizer/generator (Read 2 times) previous topic - next topic

yair

i spent a few nights trying to get reliable communication with several Ethernet shields (http://i.imgur.com/SMa8q.png)
finaly i found i was giving the same MAC address to all... grrr...

anyways, a comment in this thread mentioned it could be nice to randomize a mac address by time of day or whatever to avoid collisions.

anyone care to help code this snippet?

byte mac[] = {  
 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x10 };


keywords: multipale freeze udp hang several Ethernet shields

JimboZA

I always thought the MAC address was unique to a hardware interface and therefore a) allocated at the factory and b) therefore fixed over time.
Roy from ITCrowd: Have you tried turning it off an on again?
I'm on LinkedIn: http://www.linkedin.com/in/jimbrownza

zoomkat


I always thought the MAC address was unique to a hardware interface and therefore a) allocated at the factory and b) therefore fixed over time.


I think that was an origional intent for devices like ethernet cards for lan identification purposes, but not allways required.
Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

kg4wsv

There are classes of ethernet addresses much like there are classes of IP addresses.

There's the broadcast address (FFFFFFFFFFFF),  There's a block of multicast addresses, the block of globally administered addresses, and a block of "locally administered" addresses.  The second lowest bit in the first octet (i.e x020000000000) designates a locally administered address.  That bit should be set in any address you generate.

The lowest bit in the first octet (x010000000000) indicates a multicast address; it must not be set in any address you generate.

It appears to me that the wiznet people cheaped out either because they didn't want to buy an OUI and assign unique addresses, or they didn't want he fabrication complexity of uniquely addressing the parts.

As for "random" address generation based on time-of-day of system start: what happens when there's a power outage, and all of them start at exactly the same time?

I would set aside 6 bytes in EEPROM and hard code a unique locally administered address on each one of them.  That's a bit more work, but it is a true solution, as opposed to a hack that may or may not work every time.

-j

yair

#4
Jul 04, 2012, 02:05 pm Last Edit: Jul 04, 2012, 06:27 pm by yair Reason: 1
thanks for the detailed reaply,
my needs are basic
currently i upload onto EEPROM a unique IP in the 10.0.0.xx rangee
and then upload a general program to all boards that quarry each boards unique EEPROM settings

i think best solution is somehow take that unique ip suffix and use it to influance the mac address

kg4wsv

Quote
unique ip suffix and use it to influance the mac address


Sure, just use all 4 octets of the IP as the last 4 octets of the MAC.  Use 0xDE 0xAD for the first two MAC octets and you're good to go.

-j

yair

#6
Jul 04, 2012, 06:33 pm Last Edit: Jul 04, 2012, 06:36 pm by yair Reason: 1
here  is the EEFROM code im uploading
can i mix octates and bytes in the MAC array?
i now manualy set the last bit of IP and MAC to 13. how to automate it?
i can hardcode it, but just for knowledge sake.

EEPROM_settings_write_ARD.ino
Code: [Select]

//code for write/read from EEPROM the ip, mac and gateway data
//EEPROM MAC and IP setter
//http://arduino.cc/playground/Code/EEPROMWriteAnything
//http://arduino.cc/forum/index.php/topic,64673.0.html

#include <EEPROM.h>
#include <avr/eeprom.h>
// values saved in EEPROM

struct NET_t
{
 byte   MAC[6];
 byte   IP[4];  
 byte   GATE[4];
 short  myPort;             // should be an uint16_t myPort  !!! range = 0..65535
 short  serverPort;        // idem
}
LAN =
{
 {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x13} // *** change last bit *****
 ,
 {10,0,0,13} // ***  change ip ****
 ,
 {10,0,0,1}
 ,
 6666
 ,
 9999
};


void setup(){
 eeprom_write_block((const void*)&LAN, (void*)0, sizeof(LAN)); //write
 //eeprom_read_block((void*)&LAN, (void*)0, sizeof(LAN)); //read
}

void loop(){

}


EEPROM_settings_read_ARD.ino
Code: [Select]

#include <EEPROM.h>
#include <avr/eeprom.h>


struct NET_t
{
  byte   MAC[6];
  byte   IP[4];   
  byte   GATE[4];
  short  myPort;             // should be an uint16_t myPort  !!! range = 0..65535
  short  serverPort;        // idem

LAN;

//http://arduino.cc/forum/index.php/topic,64673.0.html

void setup(){
  //eeprom_write_block((const void*)&LAN, (void*)0, sizeof(LAN)); //write
  eeprom_read_block((void*)&LAN, (void*)0, sizeof(LAN)); //read

  Serial.begin(9600);

  Serial.print("MAC: ");
  for (int i; i < 6; i ++) {
    Serial.print(LAN.MAC[i]);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("IP: ");
  for (int i ; i < 4; i ++) {
    Serial.print(LAN.IP[i]);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("GATE: ");
  for (int i; i < 4; i ++) {
    Serial.print(LAN.GATE[i]);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("myPort: ");
  Serial.println(LAN.myPort);

  Serial.print("serverPort: ");
  Serial.println(LAN.serverPort);
}

void loop(){

}

kg4wsv

set the IP (hard code or fetch from EEPROM), then

Code: [Select]
mac[0] = 0xde;
mac[1] = 0xad;
for (i=0; i<4; i++)
{
    mac[i+2] = ip[i];
}


-j

yair

easy, thanks :)

Code: [Select]


#include <EEPROM.h>
#include <avr/eeprom.h>

struct NET_t
{
  byte   IP[4];
  byte   MAC[6];
  byte   GATE[4];
  short  myPort;             // should be an uint16_t myPort  !!! range = 0..65535
  short  serverPort;       
}
LAN =
{
  {
    10,0,0,13  } // ***** change ip ********
  ,
  {
     0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x03  } // will take ip as last 4 bits
  ,
  {
    10,0,0,1  }
  ,
  6666
    ,
  9999
};


void setup(){

  for (int i=0; i<4; i++)
  {
    LAN.MAC[i+2] = LAN.IP[i];
  }
 
  Serial.begin(9600);

  Serial.print("MAC: ");
  for (int i; i < 6; i ++) {
    Serial.print(LAN.MAC[i]);
    Serial.print(".");
  } //output "MAC: 222.173.10.0.0.13"
 
  eeprom_write_block((const void*)&LAN, (void*)0, sizeof(LAN)); //write
  //eeprom_read_block((void*)&LAN, (void*)0, sizeof(LAN)); //read
}

void loop(){

}



Go Up