GhostofGoes/getmac

`getmac` incorrectly formats MAC address?

tonycassara opened this issue ยท 7 comments

Describe the bug
When trying to grab the MAC address for my wireless TV device, the getmac command returns the wrong address. Let's say my actual address is 30:7b:45:3b:02:6c but then getmac returns 03:07:b4:53:b2:6c. I believe it is removing the leading zero from the 2nd to last tuple and appending another leading zero to the front of the address. The format returned by getmac is invalid with the application I'm using wakeonlan it wants the first address.

To Reproduce
Run arp -a on your network and find an address with a leading zero tuple (it will probably appear to be a single digit e.g. 2 vs 02). Then use getmac on that same IP address. It seems pretty consistent that it appends a leading zero to the entire MAC address, regardless of where the digit is missing.

Expected behavior
I believe it should have appended the leading zero to the 2nd to last tuple in my example above. The reality is I know next to nothing about MAC addresses so if I'm incorrect someone please educate me :)

System info
(please complete the following information):

  • OS name: Mac OS Ventura
  • OS Version: 13.2
  • Python version: 3.10
  • getmac version: 0.9.1

Additional context
Add any other context about the problem here.

The issue seems to be isolated to the UuidArpGetNode method. arpvariousargs returns the correct address.

(lgtv-venv) tjones@Taylors-MacBook-Pro lgtv-venv % getmac -v -dddd -4 172.17.0.3
DEBUG    Initializing 'ip4' method cache (platform: 'darwin')
DEBUG    27 methods available: CtypesHost, ArpingHost, ArpFile, SysIfaceFile, FcntlIface, UuidArpGetNode, UuidLanscan, GetmacExe, IpconfigExe, WmicExe, ArpExe, DarwinNetworksetupIface, ArpFreebsd, ArpOpenbsd, IfconfigWithIfaceArg, IfconfigEther, IfconfigOther, IpLinkIface, NetstatIface, IpNeighborShow, ArpVariousArgs, DefaultIfaceLinuxRouteFile, DefaultIfaceIpRoute, DefaultIfaceRouteCommand, DefaultIfaceRouteGetCommand, DefaultIfaceOpenBsd, DefaultIfaceFreeBsd
DEBUG    9 type-filtered methods for 'ip4': CtypesHost, ArpingHost, ArpFile, UuidArpGetNode, ArpExe, ArpFreebsd, ArpOpenbsd, IpNeighborShow, ArpVariousArgs
DEBUG    3 platform-filtered methods for 'darwin' (method_type='ip4'): ArpingHost, UuidArpGetNode, ArpVariousArgs
DEBUG    Test failed for method 'ArpingHost'
DEBUG    2 tested methods for 'ip4': UuidArpGetNode, ArpVariousArgs
DEBUG    Current method cache: {'ip4': 'UuidArpGetNode', 'ip6': 'None', 'iface': 'None', 'default_iface': 'None'}
DEBUG    Current fallback cache: {'ip4': '[<getmac.getmac.ArpVariousArgs object at 0x104ef8670>]', 'ip6': '[]', 'iface': '[]', 'default_iface': '[]'}
DEBUG    Finished initializing 'ip4' method cache
DEBUG    Attempting to populate ARP table with UDP packet to 172.17.0.3:55555
DEBUG    Attempting get() (method='UuidArpGetNode', method_type='ip4', arg='172.17.0.3')
DEBUG    Raw MAC found: 0E:45:F1:67:22:2A
DEBUG    getmac took 0.0132 seconds
0e:45:f1:67:22:2a
(lgtv-venv) tjones@Taylors-MacBook-Pro lgtv-venv % getmac -v -dddd -4 172.17.0.3 --force-method ArpVariousArgs
DEBUG    Initializing 'ip4' method cache (platform: 'darwin')
DEBUG    27 methods available: CtypesHost, ArpingHost, ArpFile, SysIfaceFile, FcntlIface, UuidArpGetNode, UuidLanscan, GetmacExe, IpconfigExe, WmicExe, ArpExe, DarwinNetworksetupIface, ArpFreebsd, ArpOpenbsd, IfconfigWithIfaceArg, IfconfigEther, IfconfigOther, IpLinkIface, NetstatIface, IpNeighborShow, ArpVariousArgs, DefaultIfaceLinuxRouteFile, DefaultIfaceIpRoute, DefaultIfaceRouteCommand, DefaultIfaceRouteGetCommand, DefaultIfaceOpenBsd, DefaultIfaceFreeBsd
DEBUG    9 type-filtered methods for 'ip4': CtypesHost, ArpingHost, ArpFile, UuidArpGetNode, ArpExe, ArpFreebsd, ArpOpenbsd, IpNeighborShow, ArpVariousArgs
DEBUG    3 platform-filtered methods for 'darwin' (method_type='ip4'): ArpingHost, UuidArpGetNode, ArpVariousArgs
DEBUG    Test failed for method 'ArpingHost'
DEBUG    2 tested methods for 'ip4': UuidArpGetNode, ArpVariousArgs
DEBUG    Current method cache: {'ip4': 'UuidArpGetNode', 'ip6': 'None', 'iface': 'None', 'default_iface': 'None'}
DEBUG    Current fallback cache: {'ip4': '[<getmac.getmac.ArpVariousArgs object at 0x102fe4610>]', 'ip6': '[]', 'iface': '[]', 'default_iface': '[]'}
DEBUG    Finished initializing 'ip4' method cache
DEBUG    Attempting to populate ARP table with UDP packet to 172.17.0.3:55555
WARNING  Forcing method 'arpvariousargs' to be used for 'ip4' lookup (arg: '172.17.0.3')
DEBUG    Running: '/usr/sbin/arp  172.17.0.3'
DEBUG    Output from '/usr/sbin/arp' command: b'pikvm.local.lan (172.17.0.3) at e4:5f:1:67:22:2a on en0 ifscope [ethernet]\n'
DEBUG    Raw MAC found: e4:5f:1:67:22:2a
DEBUG    getmac took 0.0049 seconds
DEBUG    Length of MAC e4:5f:1:67:22:2a is 16, padding single-character octets with zeros
e4:5f:01:67:22:2a

I dug a little deeper on this and it looks like the issue is upstream with the uuid module. _MAC_OMITS_LEADING_ZEROES is set to False for Darwin. Also, the _find_mac_near_keyword function called by _arp_getnode does not call the _parse_mac function that is used to add the leading zeros back.
https://github.com/python/cpython/blob/v3.10.9/Lib/uuid.py#L65

I opened an issue in the python repo:
python/cpython#101531

@t-jonesy thank you!!! I am not a Python developer so I'm way out of my league here haha.

@t-jonesy Thank you for digging into this. The simple fix here short-term is to move UuidArpGetnode down in the list of methods, so ArpVariousArgs gets used before it. Should a quick fix.

Side chatter, this is one more reason to do away with the method of abusing the internal functionality of uuid. It's relying on internal functions of uuid which change between versions of Python. This isn't the first issue I've had with it, and I may do away with it in 1.0.0 (hence the TODO in the code).

Fix is published in 0.9.2. Let me know if that works for you, I don't have a Mac so I have no way to test it ๐Ÿ˜…

@GhostofGoes thanks; it's working as expected now

(lgtv-venv) tjones@Taylors-MBP lgtv-venv % getmac --version 
getmac 0.9.2
(lgtv-venv) tjones@Taylors-MBP lgtv-venv % getmac -v -dddd -4 172.17.0.3
DEBUG    Initializing 'ip4' method cache (platform: 'darwin')
DEBUG    27 methods available: CtypesHost, ArpingHost, ArpFile, SysIfaceFile, FcntlIface, UuidLanscan, GetmacExe, IpconfigExe, WmicExe, ArpExe, DarwinNetworksetupIface, ArpFreebsd, ArpOpenbsd, IfconfigWithIfaceArg, IfconfigEther, IfconfigOther, IpLinkIface, NetstatIface, IpNeighborShow, ArpVariousArgs, UuidArpGetNode, DefaultIfaceLinuxRouteFile, DefaultIfaceIpRoute, DefaultIfaceRouteCommand, DefaultIfaceRouteGetCommand, DefaultIfaceOpenBsd, DefaultIfaceFreeBsd
DEBUG    9 type-filtered methods for 'ip4': CtypesHost, ArpingHost, ArpFile, ArpExe, ArpFreebsd, ArpOpenbsd, IpNeighborShow, ArpVariousArgs, UuidArpGetNode
DEBUG    3 platform-filtered methods for 'darwin' (method_type='ip4'): ArpingHost, ArpVariousArgs, UuidArpGetNode
DEBUG    Test failed for method 'ArpingHost'
DEBUG    2 tested methods for 'ip4': ArpVariousArgs, UuidArpGetNode
DEBUG    Current method cache: {'ip4': 'ArpVariousArgs', 'ip6': 'None', 'iface': 'None', 'default_iface': 'None'}
DEBUG    Current fallback cache: {'ip4': '[<getmac.getmac.UuidArpGetNode object at 0x1052c30d0>]', 'ip6': '[]', 'iface': '[]', 'default_iface': '[]'}
DEBUG    Finished initializing 'ip4' method cache
DEBUG    Attempting to populate ARP table with UDP packet to 172.17.0.3:55555
DEBUG    Attempting get() (method='ArpVariousArgs', method_type='ip4', arg='172.17.0.3')
DEBUG    Running: '/usr/sbin/arp  172.17.0.3'
DEBUG    Output from '/usr/sbin/arp' command: b'pikvm.local.lan (172.17.0.3) at e4:5f:1:67:22:2a on en0 ifscope [ethernet]\n'
DEBUG    Raw MAC found: e4:5f:1:67:22:2a
DEBUG    getmac took 0.0034 seconds
DEBUG    Length of MAC e4:5f:1:67:22:2a is 16, padding single-character octets with zeros
e4:5f:01:67:22:2a

Works for me too thank you so much!