467,888 Members | 1,461 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,888 developers. It's quick & easy.

14 byte array (MAC address) to 48 bits (6 bytes)...

First,

Sorry for the cross-post :p OK, in Linux I can obtain the MAC address
using socket(), ioctl() etc. and a few data structures. No problem.
However, the resulting MAC is stored in a 14 byte char array
(sockaddr.sa_data). However, a MAC address is 48-bits! The MAC (as in
the char array) is obviously the printable form of:

00efc8346b72

or whatever. So that last '7' and '2' is in fact meant to be the 1 byte
72 right? How is this array shifted down to a 6 byte array or even
better, what I really want is the least significant 32-bits to stick in
an unsigned int!

Any help appreciated!

Jim

Jul 28 '06 #1
  • viewed: 9940
Share:
9 Replies
James Vanns wrote:
First,

Sorry for the cross-post :p OK, in Linux I can obtain the MAC address
using socket(), ioctl() etc. and a few data structures. No problem.
However, the resulting MAC is stored in a 14 byte char array
(sockaddr.sa_data). However, a MAC address is 48-bits! The MAC (as in
the char array) is obviously the printable form of:

00efc8346b72

or whatever. So that last '7' and '2' is in fact meant to be the 1 byte
72 right? How is this array shifted down to a 6 byte array or even
better, what I really want is the least significant 32-bits to stick in
an unsigned int!

Any help appreciated!
I'd love to help but I have no idea what you're talking about !
Could you express in abstract terms what you're trying to achieve
without mentioning MAC's , Linux , ioctl etc. ?

Jul 28 '06 #2

James Vanns wrote:
First,

Sorry for the cross-post :p OK, in Linux I can obtain the MAC address
using socket(), ioctl() etc. and a few data structures. No problem.
However, the resulting MAC is stored in a 14 byte char array
(sockaddr.sa_data). However, a MAC address is 48-bits! The MAC (as in
the char array) is obviously the printable form of:

00efc8346b72

or whatever. So that last '7' and '2' is in fact meant to be the 1 byte
72 right? How is this array shifted down to a 6 byte array or even
better, what I really want is the least significant 32-bits to stick in
an unsigned int!

Any help appreciated!

Jim
Hi,

I think you probably want code like this, probably with some added
error
checking...

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *pMac = "00efc8346b72";
unsigned long iMac = strtoul(&pMac[4], NULL, 16);

printf("pMac '%s' -iMac '%lu' (=%lx)\n",
pMac, iMac, iMac);

return 0;
}

-David

Jul 28 '06 #3
OK, I've come up with this code. I know it's C++ (sorry wrong news
group) but I *was* going to use just C. However, do you think I'm on
the right track?

static const uint32_t mac2int (const string &p_nic, const string
&p_mac) {
uint32_t imac = 0;
string mac (p_mac); // 00:02:B3:14:03:D7
mac.erase (remove (mac.begin (), mac.end (), ':'), mac.end ()); //
0002B31403D7

for (uint i = 0 ; i < sizeof (uint) * 2 ; i += 2) {
char b[3];
b[2] = '\0';
b[1] = *(mac.end () - (i + 1)); // 7
b[0] = *(mac.end () - (i + 2)); // D
imac = (imac << 8) | strtoul (b, NULL, 16); // The important bit!
}

return imac;
}

Ta,

Jim

David Resnick wrote:
James Vanns wrote:
First,

Sorry for the cross-post :p OK, in Linux I can obtain the MAC address
using socket(), ioctl() etc. and a few data structures. No problem.
However, the resulting MAC is stored in a 14 byte char array
(sockaddr.sa_data). However, a MAC address is 48-bits! The MAC (as in
the char array) is obviously the printable form of:

00efc8346b72

or whatever. So that last '7' and '2' is in fact meant to be the 1 byte
72 right? How is this array shifted down to a 6 byte array or even
better, what I really want is the least significant 32-bits to stick in
an unsigned int!

Any help appreciated!

Jim

Hi,

I think you probably want code like this, probably with some added
error
checking...

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *pMac = "00efc8346b72";
unsigned long iMac = strtoul(&pMac[4], NULL, 16);

printf("pMac '%s' -iMac '%lu' (=%lx)\n",
pMac, iMac, iMac);

return 0;
}

-David
Jul 28 '06 #4
In article <11**********************@75g2000cwc.googlegroups. com>,
James Vanns <ja*********@gmail.comwrote:
>OK, I've come up with this code. I know it's C++ (sorry wrong news
group) but I *was* going to use just C. However, do you think I'm on
the right track?
>static const uint32_t mac2int (const string &p_nic, const string
&p_mac) {
uint32_t imac = 0;
string mac (p_mac); // 00:02:B3:14:03:D7
mac.erase (remove (mac.begin (), mac.end (), ':'), mac.end ()); //
0002B31403D7
That code violates the initialy stated condition that the MAC
was stored in a 14 byte array and therefore is not suitable
for the original purpose.

If you are going to work with the human-readable textual form of MACs,
then you need to be concerned with the possibility that leading
zeroes have been supressed, such as 0:2:B3:14:3:D7 .
--
Is there any thing whereof it may be said, See, this is new? It hath
been already of old time, which was before us. -- Ecclesiastes
Jul 28 '06 #5
James Vanns wrote:
OK, I've come up with this code. I know it's C++ (sorry wrong news
group) but I *was* going to use just C. However, do you think I'm on
the right track?

static const uint32_t mac2int (const string &p_nic, const string
&p_mac) {
uint32_t imac = 0;
string mac (p_mac); // 00:02:B3:14:03:D7
mac.erase (remove (mac.begin (), mac.end (), ':'), mac.end ()); //
0002B31403D7

for (uint i = 0 ; i < sizeof (uint) * 2 ; i += 2) {
char b[3];
b[2] = '\0';
b[1] = *(mac.end () - (i + 1)); // 7
b[0] = *(mac.end () - (i + 2)); // D
imac = (imac << 8) | strtoul (b, NULL, 16); // The important bit!
}

return imac;
}

Ta,

Jim
People frown on C++ code (off topic) and on top-posting (bad practice)
in comp.lang.c, just FYI. Anyway, I won't comment specifically on C++
aspects of the code in comp.lang.c (followups set to comp.lang.c++ and
comp.unix.programmer).

It seems to me that you might as well convert the whole thing (starting
at the 5th character) at once after removing the ':' characters rather
than do the convert two characters/shift thing unless you somehow think
the format of a MAC address will change.

-David

Jul 28 '06 #6
<sp****@gmail.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
James Vanns wrote:
>Sorry for the cross-post :p OK, in Linux I can obtain the MAC
address using socket(), ioctl() etc. and a few data structures.
No problem. However, the resulting MAC is stored in a 14 byte
char array (sockaddr.sa_data). However, a MAC address is
48-bits! The MAC (as in the char array) is obviously the printable
form of:

00efc8346b72

or whatever. So that last '7' and '2' is in fact meant to be the 1
byte
72 right? How is this array shifted down to a 6 byte array or even
better, what I really want is the least significant 32-bits to
stick in
an unsigned int!

Any help appreciated!

I'd love to help but I have no idea what you're talking about !
Could you express in abstract terms what you're trying to achieve
without mentioning MAC's , Linux , ioctl etc. ?
He wants to turn this:

char printablemac[14] = "00efc8346b72";

into this:

unsigned char binarymac[6] = { 0x00, 0xef, 0xc8, 0x34, 0x6b, 0x72 };

or this:

unsigned long longmac = 0xc8346b72;

or this:

unsigned long long longlongmac = 0x00efc8346b72;

The answers for the first and the latter two are rather different, but
David Resnick provided a reasonable answer to the middle option.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

--
Posted via a free Usenet account from http://www.teranews.com

Jul 28 '06 #7
I thought that someone may have noticed this. The array is defined in
the linux socket.h header file as being 14 bytes in size. However, you
only need 12 for a hex rep of a 48-bit number which is what the MAC
address is. I'm only working with what I've got ;) Basically I built
the std::string from the 14 byte char array taking only bytes 12 -0.
This seems to work fine on the ~1000 linux machines I've tried. I'm not
bothered with portability at the moment. The colons are never use at
this level of the api.

Have anything else to add?

Jim

Walter Roberson wrote:
In article <11**********************@75g2000cwc.googlegroups. com>,
James Vanns <ja*********@gmail.comwrote:
OK, I've come up with this code. I know it's C++ (sorry wrong news
group) but I *was* going to use just C. However, do you think I'm on
the right track?
static const uint32_t mac2int (const string &p_nic, const string
&p_mac) {
uint32_t imac = 0;
string mac (p_mac); // 00:02:B3:14:03:D7
mac.erase (remove (mac.begin (), mac.end (), ':'), mac.end ()); //
0002B31403D7

That code violates the initialy stated condition that the MAC
was stored in a 14 byte array and therefore is not suitable
for the original purpose.

If you are going to work with the human-readable textual form of MACs,
then you need to be concerned with the possibility that leading
zeroes have been supressed, such as 0:2:B3:14:3:D7 .
--
Is there any thing whereof it may be said, See, this is new? It hath
been already of old time, which was before us. -- Ecclesiastes
Jul 28 '06 #8
I think Stephen and David have hit the nail on the head. I'm close to
getting what I want so I'm sure I'll crack it now.

Ta,

Jim

James Vanns wrote:
I thought that someone may have noticed this. The array is defined in
the linux socket.h header file as being 14 bytes in size. However, you
only need 12 for a hex rep of a 48-bit number which is what the MAC
address is. I'm only working with what I've got ;) Basically I built
the std::string from the 14 byte char array taking only bytes 12 -0.
This seems to work fine on the ~1000 linux machines I've tried. I'm not
bothered with portability at the moment. The colons are never use at
this level of the api.

Have anything else to add?

Jim

Walter Roberson wrote:
In article <11**********************@75g2000cwc.googlegroups. com>,
James Vanns <ja*********@gmail.comwrote:
>OK, I've come up with this code. I know it's C++ (sorry wrong news
>group) but I *was* going to use just C. However, do you think I'm on
>the right track?
>static const uint32_t mac2int (const string &p_nic, const string
>&p_mac) {
uint32_t imac = 0;
string mac (p_mac); // 00:02:B3:14:03:D7
mac.erase (remove (mac.begin (), mac.end (), ':'), mac.end ()); //
>0002B31403D7
That code violates the initialy stated condition that the MAC
was stored in a 14 byte array and therefore is not suitable
for the original purpose.

If you are going to work with the human-readable textual form of MACs,
then you need to be concerned with the possibility that leading
zeroes have been supressed, such as 0:2:B3:14:3:D7 .
--
Is there any thing whereof it may be said, See, this is new? It hath
been already of old time, which was before us. -- Ecclesiastes
Jul 28 '06 #9
Stephen Sprunk wrote:
<sp****@gmail.comwrote in message
news:11*********************@i42g2000cwa.googlegro ups.com...
James Vanns wrote:
Sorry for the cross-post :p OK, in Linux I can obtain the MAC
address using socket(), ioctl() etc. and a few data structures.
No problem. However, the resulting MAC is stored in a 14 byte
char array (sockaddr.sa_data). However, a MAC address is
48-bits! The MAC (as in the char array) is obviously the printable
form of:

00efc8346b72

or whatever. So that last '7' and '2' is in fact meant to be the 1
byte
72 right? How is this array shifted down to a 6 byte array or even
better, what I really want is the least significant 32-bits to
stick in
an unsigned int!

Any help appreciated!
I'd love to help but I have no idea what you're talking about !
Could you express in abstract terms what you're trying to achieve
without mentioning MAC's , Linux , ioctl etc. ?

He wants to turn this:

char printablemac[14] = "00efc8346b72";

into this:

unsigned char binarymac[6] = { 0x00, 0xef, 0xc8, 0x34, 0x6b, 0x72 };

or this:

unsigned long longmac = 0xc8346b72;

or this:

unsigned long long longlongmac = 0x00efc8346b72;

The answers for the first and the latter two are rather different, but
David Resnick provided a reasonable answer to the middle option.
Thank you. This not only makes sense but is actually on topic.

But my charitable mood has left me plus the opening poster says he
has solved the problem anyway.

Spiros Bousbouras

Jul 28 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by David Cook | last post: by
5 posts views Thread by Gidraz | last post: by
4 posts views Thread by Lance | last post: by
3 posts views Thread by simonc | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.