Page 1 of 1

How to get MAC address from C

Posted: Sat Jun 04, 2016 10:02 pm
by softwarefailure
How can I get the MAC address on AmigaOS 4 from C?

Re: How to get MAC address from C

Posted: Sun Jun 05, 2016 10:50 am
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 )
  {
..

Re: How to get MAC address from C

Posted: Sun Jun 05, 2016 8:58 pm
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...

Re: How to get MAC address from C

Posted: Sun Jun 05, 2016 10:48 pm
by nbache
So what did size contain after your last attempt?

Best regards,

Niels

Re: How to get MAC address from C

Posted: Mon Jun 06, 2016 12:38 am
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.

Re: How to get MAC address from C

Posted: Mon Jun 06, 2016 5:40 pm
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.

Re: How to get MAC address from C

Posted: Mon Jun 06, 2016 10:43 pm
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

Re: How to get MAC address from C

Posted: Tue Jun 07, 2016 1:11 pm
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.

Re: How to get MAC address from C

Posted: Tue Jun 07, 2016 10:31 pm
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

Re: How to get MAC address from C

Posted: Wed Jun 08, 2016 10:01 am
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 :(