How to get MAC address from C

This forum is for general developer support questions.
Post Reply
softwarefailure
Posts: 112
Joined: Fri Feb 14, 2014 10:29 pm

How to get MAC address from C

Post by softwarefailure »

How can I get the MAC address on AmigaOS 4 from C?
User avatar
javierdlr
Beta Tester
Beta Tester
Posts: 389
Joined: Sun Jun 19, 2011 10:13 pm
Location: Donostia (GUIPUZCOA) - Spain
Contact:

Re: How to get MAC address from C

Post by javierdlr »

You can check NetSpeedometer sources, as it shows MAC address on GUI.

IFQ_HardwareAddress,     HardwareAddressText,

Code: Select all

..
if ( ISocket->QueryInterfaceTags( Label_p, /* it can' t be longer than 15 chars */
                                    IFQ_Address,             &AddressBuffer,
                                    /* IFQ_DestinationAddress,  &DestinationAddressBuffer, */
                                    IFQ_NetMask,             &NetMaskBuffer,
                                    IFQ_PrimaryDNSAddress,   &PrimaryDNSAddressBuffer,
                                    IFQ_SecondaryDNSAddress, &SecondaryDNSAddressBuffer,
                                    IFQ_AddressBindType,     &AddressBindType,
                                    /* --- */
                                    IFQ_HardwareType,        &HardwareType,
                                    IFQ_HardwareAddressSize, &HardwareAddressSize,
                                    IFQ_HardwareAddress,     HardwareAddressText,
                                    IFQ_BPS,                 &BPS,
                                    IFQ_State,               &State,
                                    /* --- */
                                    IFQ_GetBytesIn,  &GetBytesIn,
                                    IFQ_GetBytesOut, &GetBytesOut,
                                    TAG_DONE ) != 0 )
  {
..
softwarefailure
Posts: 112
Joined: Fri Feb 14, 2014 10:29 pm

Re: How to get MAC address from C

Post by softwarefailure »

Thanks, this does the trick but there seems to be an error in the documentation. The doc says:

Code: Select all

	IFQ_HardwareAddress (UBYTE *) - Retrieve the hardware address
	    associated with this interface; a maximum of 16 bytes
	    will be copied.
But doing this leads to a crash:

Code: Select all

UBYTE buf[17];
ULONG size;

ISocket->QueryInterfaceTags( interface,
                                    IFQ_HardwareAddressSize, &size,
                                    IFQ_HardwareAddress,     buf,
                                    TAG_DONE );
Increasing the buffer size like this solves the problem:

Code: Select all

UBYTE buf[128];
ULONG size;

ISocket->QueryInterfaceTags( interface,
                                    IFQ_HardwareAddressSize, &size,
                                    IFQ_HardwareAddress,     buf,
                                    TAG_DONE );
So it looks like more than just 16 bytes are copied...
User avatar
nbache
Beta Tester
Beta Tester
Posts: 1714
Joined: Mon Dec 20, 2010 7:25 pm
Location: Copenhagen, Denmark
Contact:

Re: How to get MAC address from C

Post by nbache »

So what did size contain after your last attempt?

Best regards,

Niels
User avatar
tonyw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 1479
Joined: Wed Mar 09, 2011 1:36 pm
Location: Sydney, Australia

Re: How to get MAC address from C

Post by tonyw »

Perhaps you should call the function with just the "HardwareAddressSize" tag first, to find out how big it is going to be.
Then you can allocate a buffer big enough for the result and call the function with the "HardwareAddress" tag.

After all, the simplest MAC address form "aa:bb:cc:dd:ee:ff" takes up 18 bytes, including the null at the end of the string.

Submitted bug report #9567.
cheers
tony
softwarefailure
Posts: 112
Joined: Fri Feb 14, 2014 10:29 pm

Re: How to get MAC address from C

Post by softwarefailure »

Size is always set to 48, i.e. 6 bytes, which is right for a MAC address but as I've said, it seems to copy more than 17 bytes to the destination buffer because passing a buffer of 17 bytes causes a crash. The reason why I chose a 17 byte buffer was that the documentation states:

Code: Select all

	IFQ_HardwareAddress (UBYTE *) - Retrieve the hardware address
	    associated with this interface; a maximum of 16 bytes
	    will be copied. 
@tonyw:
QueryInterfaceTags() doesn't return the MAC address in the form of aa:bb:cc:dd:ee:ff but as an array of uint8 with 6 entries, i.e. 48 bits. So strictly speaking 6 bytes should already be sufficient but I was following the doc guide lines which says that a maximum of 16 bytes can ever be copied.
User avatar
nbache
Beta Tester
Beta Tester
Posts: 1714
Joined: Mon Dec 20, 2010 7:25 pm
Location: Copenhagen, Denmark
Contact:

Re: How to get MAC address from C

Post by nbache »

softwarefailure wrote:Size is always set to 48, i.e. 6 bytes, which is right for a MAC address but as I've said, it seems to copy more than 17 bytes to the destination buffer because passing a buffer of 17 bytes causes a crash.
Yeah, that does indeed sound like a bug, then. Good to see Tony filed it already.
The reason why I chose a 17 byte buffer was that the documentation states:

Code: Select all

	IFQ_HardwareAddress (UBYTE *) - Retrieve the hardware address
	    associated with this interface; a maximum of 16 bytes
	    will be copied. 
Right, that may be a (documentation?) bug too. I see it is noted in the bug report as well.

It looks like the HardwareAddressSize wasn't meant to be a (string) buffer length at all, but just the bit length of the MAC address - as if that would ever change? A bit confusing.

BTW, did you check what actually ended up in your buf once it was big enough to avoid the crash - i.e. did it look like the binary representation (6 uint8 entries), or did it look like the string representation? There might be more than one documentation bug ...

Best regards,

Niels
Olaf Barthel
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 9
Joined: Mon Jun 20, 2011 3:22 pm

Re: How to get MAC address from C

Post by Olaf Barthel »

nbache wrote:
softwarefailure wrote:Size is always set to 48, i.e. 6 bytes, which is right for a MAC address but as I've said, it seems to copy more than 17 bytes to the destination buffer because passing a buffer of 17 bytes causes a crash.
Yeah, that does indeed sound like a bug, then. Good to see Tony filed it already.
I just checked the code and found that QueryInterfaceTags() copies as many bytes as there are bits in the address. Hence, for an Ethernet MAC address 48 bytes are copied, the first six of which will contain valid data and the remaining 42 being junk that only serves to overwrite data that should not be harmed.

This is definitely a bug, and it's the only bug of this kind in Roadshow. All other places which copy the SANA-II station address will use the number of bytes required to do so, not the length in bits.
User avatar
nbache
Beta Tester
Beta Tester
Posts: 1714
Joined: Mon Dec 20, 2010 7:25 pm
Location: Copenhagen, Denmark
Contact:

Re: How to get MAC address from C

Post by nbache »

Olaf Barthel wrote:I just checked the code and found that QueryInterfaceTags() copies as many bytes as there are bits in the address.
Oops .. he-he ... bytes, bits, what is difference ...

Best regards,

Niels
Olaf Barthel
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 9
Joined: Mon Jun 20, 2011 3:22 pm

Re: How to get MAC address from C

Post by Olaf Barthel »

nbache wrote:
Olaf Barthel wrote:I just checked the code and found that QueryInterfaceTags() copies as many bytes as there are bits in the address.
Oops .. he-he ... bytes, bits, what is difference ...

Best regards,

Niels
The difference between bits and bytes is not quite as pronounced in the network driver which fills in the data structure whose contents are what comes out as the address. The data structure member which contains the size of the address is called AddrFieldSize, which does not say anything about the unit of the length. The address field contains data which always was a multiple of 8 bits to begin with, which makes it the more puzzling why AddrFieldSize states the length in bits rather than bytes.

You have to know the context of what unit AddrFieldSize refers to, as the name of the structure member fails to steer you in the right direction. This sort of thing is common enough. It's part of what makes software development so exciting :(
Post Reply