|
Home > Archive > Unix Programming > July 2006 > 14 byte array (MAC address) to 48 bits (6 bytes)...
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
14 byte array (MAC address) to 48 bits (6 bytes)...
|
|
| James Vanns 2006-07-28, 1:24 pm |
| 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
| |
| spibou@gmail.com 2006-07-28, 1:24 pm |
| 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. ?
| |
| David Resnick 2006-07-28, 1:24 pm |
|
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
| |
| spibou@gmail.com 2006-07-28, 1:24 pm |
| spibou@gmail.com wrote:
> James Vanns wrote:
>
>
> 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. ?
I have yet to understand the secrets of USENET but I saw the message
on comp.lang.c and my reply was coloured by that. It doesn't appear
there anymore though. It may have been a Google cock-up, I don't know.
Spiros Bousbouras
| |
| James Vanns 2006-07-28, 1:24 pm |
| 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:
>
> 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
| |
| Walter Roberson 2006-07-28, 1:24 pm |
| In article <1154100811.211666.313790@75g2000cwc.googlegroups.com>,
James Vanns <james.vanns@gmail.com> 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
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
| |
| David Resnick 2006-07-28, 1:24 pm |
| 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
| |
| Stephen Sprunk 2006-07-28, 1:24 pm |
| <spibou@gmail.com> wrote in message
news:1154097683.745772.45940@i42g2000cwa.googlegroups.com...
> James Vanns wrote:
>
> 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
| |
| James Vanns 2006-07-28, 1:24 pm |
| 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 <1154100811.211666.313790@75g2000cwc.googlegroups.com>,
> James Vanns <james.vanns@gmail.com> wrote:
>
>
> 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
| |
| James Vanns 2006-07-28, 1:24 pm |
| 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:[vbcol=seagreen]
> 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:
| |
| spibou@gmail.com 2006-07-28, 1:24 pm |
| Stephen Sprunk wrote:
> <spibou@gmail.com> wrote in message
> news:1154097683.745772.45940@i42g2000cwa.googlegroups.com...
>
> 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
|
|
|
|
|