[U-Boot] MAC Address reading procedure in board.c

Hi all, I have been looking at MAC addr obtaining procedure in lib_arm/board.c and I am puzzled with this implementation :
/* MAC Address */ { int i; ulong reg; char *s, *e; char tmp[64];
i = getenv_r ("ethaddr", tmp, sizeof (tmp)); s = (i > 0) ? tmp : NULL;
*for (reg = 0; reg < 6; ++reg) { gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0; if (s) s = (*e) ? e + 1 : e;* } }
Here are my questions: 1) In which format is kept the addr in environment (i.e. why do we allocate 64 byte buffer tmp)? This is a little bit tricky to see from the code, so I thought maybe somebody will know.
2) In my opinion - there should be some delimiters (maybe ':') in this eth addr string in environment, so we are here jumping over them :* if (s) s = (*e) ? e + 1 : e; *but I still cannot see - how long are these strings between delimiters? (Because when you call simple_strtoul(), it will proceed to the first non-digit character, so who knows how long. As long as simple_stroul() is concerned, if it do not meet nonhexdigit char, it can go to Moon and beyond). Why we did not took two chars to represent each of 6 bytes + delimiters (':'), which would make 6*2 + 5 = 11, which should be the length of the tmp buffer. Then take two-by-two chars and transform them into number. What am I missing here?
Thanks and best regards, Drasko

Dear Drasko DRASKOVIC,
In message 5ec3d7930905250856k6cffb4ber261bd99f15868c19@mail.gmail.com you wrote:
I have been looking at MAC addr obtaining procedure in lib_arm/board.c and I am puzzled with this implementation :
/* MAC Address */ { int i; ulong reg; char *s, *e; char tmp[64];
i = getenv_r ("ethaddr", tmp, sizeof (tmp)); s = (i > 0) ? tmp : NULL; *for (reg = 0; reg < 6; ++reg) { gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0; if (s) s = (*e) ? e + 1 : e;* } }
That must be very old code. Please update to a recent version before trying to understand this.
Here are my questions:
- In which format is kept the addr in environment (i.e. why do we allocate
64 byte buffer tmp)? This is a little bit tricky to see from the code, so I thought maybe somebody will know.
It's stored as a string "aa:bb:cc:dd:ee:ff". 64 is sufficiently large to catch most (acccidential) incorrect input.
- In my opinion - there should be some delimiters (maybe ':') in this eth
addr string in environment, so we are here jumping over them :* if (s) s = (*e) ? e + 1 : e; *but I still cannot see - how long are these strings between delimiters?
Usually these are 2 characters long, but they can be aby size. You can write "0:1:2:3:4:5" or "0000:1:0002:2:04:000000005" as well, as long as you don't exceed the maximum of sizeof(tmp).
beyond). Why we did not took two chars to represent each of 6 bytes + delimiters (':'), which would make 6*2 + 5 = 11, which should be the length of the tmp buffer. Then take two-by-two chars and transform them into number. What am I missing here?
Why should we make such a restriction? Why do you want to force me to type two characters when one may be sufficient?
Best regards,
Wolfgang Denk

Hi Wolfgang, first of all thanks a lot for your answers.
On Mon, May 25, 2009 at 8:32 PM, Wolfgang Denk wd@denx.de wrote:
Dear Drasko DRASKOVIC,
In message 5ec3d7930905250856k6cffb4ber261bd99f15868c19@mail.gmail.com you wrote:
I have been looking at MAC addr obtaining procedure in lib_arm/board.c
and I
am puzzled with this implementation :
/* MAC Address */ { int i; ulong reg; char *s, *e; char tmp[64];
i = getenv_r ("ethaddr", tmp, sizeof (tmp)); s = (i > 0) ? tmp : NULL; *for (reg = 0; reg < 6; ++reg) { gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) :
0;
if (s) s = (*e) ? e + 1 : e;* } }
That must be very old code. Please update to a recent version before trying to understand this.
I know that you are strongly suggesting that newes code should be used, but sometimes it is just not my choice (although I always advocate for the newes version).
Here are my questions:
- In which format is kept the addr in environment (i.e. why do we
allocate
64 byte buffer tmp)? This is a little bit tricky to see from the code, so
I
thought maybe somebody will know.
It's stored as a string "aa:bb:cc:dd:ee:ff". 64 is sufficiently large to catch most (acccidential) incorrect input.
Perfect! I started jumping through the tags and got lost in the see of code. "Go to the lists...", the inner voice was telling me.
- In my opinion - there should be some delimiters (maybe ':') in this
eth
addr string in environment, so we are here jumping over them :* if (s) s = (*e) ? e + 1 : e; *but I still cannot see - how long are these strings between delimiters?
Usually these are 2 characters long, but they can be aby size. You can write "0:1:2:3:4:5" or "0000:1:0002:2:04:000000005" as well, as long as you don't exceed the maximum of sizeof(tmp).
Aaah. Now I get it ;)
beyond). Why we did not took two chars to represent each of 6 bytes + delimiters (':'), which would make 6*2 + 5 = 11, which should be the
length
of the tmp buffer. Then take two-by-two chars and transform them into number. What am I missing here?
Why should we make such a restriction? Why do you want to force me to type two characters when one may be sufficient?
You are absolutly right (I guess that was frustration of the moment talking here).
Best regards,
Wolfgang Denk
Once again, thanks for your valuable answers. Perfect support - as always ;).
Best regards, Drasko
participants (2)
-
Drasko DRASKOVIC
-
Wolfgang Denk