Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_mac_address() is caching an old mac address, no longer present in local ARP #76

Open
lucasbritosig opened this issue Jul 14, 2022 · 7 comments
Assignees
Labels

Comments

@lucasbritosig
Copy link

Describe the bug
get_mac_address() is caching an old mac address for a given IP, even when it has timeout from OS ARP table.
Only an explicit delete of the ARP entry on the OS make it return '00:00:00:00:00:00' again.

To Reproduce

  • Force ARP resolution for an IP1 (a device in LAN)
  • Change IP from IP1 to IP2 on the target device.
  • Wait ARP entry timeout (or more)
  • execute get_mac_address(ip=IP1), will still get the device MAC (which is now IP2) instead of '00:00:00:00:00:00'.

OS ARP for IP1:
$ arp 192.168.88.101 -v
Address HWtype HWaddress Flags Mask Iface
192.168.88.101 (incomplete) wlp3s0
Entries: 20 Skipped: 19 Found: 1

Expected behavior
Expects '00:00:00:00:00:00'

System info
(please complete the following information):

  • OS name: Ubuntu
  • OS Version: 20.04.4 LTS focal
  • Python version: 3.8.10 x64

Additional context
Running "arp -d 192.168.88.101" solves the issue.

@lucasbritosig
Copy link
Author

Also tested in
Ubuntu 16.04.7 LTS
Python 3.5.2
(o a wired NIC)

@GhostofGoes
Copy link
Owner

GhostofGoes commented Jul 19, 2022

Hmm, by default on Ubuntu getmac will just read the ARP entries from /proc/net/arp directly. Can you post a dump of your ARP table after IP has been changed to IP2 and a ping has been performed? Is the old entry for IP1 still in the table? I'm curious if there are two entries in the table, and if so, maybe it's a simple fix for the parser to select the correct entry.

Also, I should note that getmac avoids shelling out to arp whenever possible since that's relatively expensive (100s of ms to seconds).

@lucasbritosig
Copy link
Author

You are right, both entries in /proc/net/arp... Also arpreq is returning the same
But getmacbyip (capy.layers.l2) works fine (192.168.0.47 is the connected one)

$ cat /proc/net/arp
IP address       HW type     Flags       HW address            Mask     Device
192.168.0.46     0x1         0x0         f2:1e:63:ac:de:24     *        wlp3s0
192.168.0.47     0x1         0x2         f2:1e:63:ac:de:24     *        wlp3s0
>>> import getmac
>>> getmac.get_mac_address(ip='192.168.0.46')
'f2:1e:63:ac:de:24'
>>> getmac.get_mac_address(ip='192.168.0.47')
'f2:1e:63:ac:de:24'
>>> from scapy.layers.l2 import getmacbyip
>>> getmacbyip('192.168.0.47')
'f2:1e:63:ac:de:24'
>>> getmacbyip('192.168.0.46')
>>> 

@lucasbritosig
Copy link
Author

Looks like flags need to be parsed (?)

0x0 incomplete
0x2 complete
0x6 complete and manually set

@lucasbritosig
Copy link
Author

@GhostofGoes
Copy link
Owner

Thanks for investigating and the additional information. It's definitely a bug, and one that should be relatively easy to fix. I'll add a check that the flag != 0x0, which should do the trick, unless there's an edge case that it misses.

Since the refactor for 0.9.0 is nearing completion, I'll just implement it in that branch and include the fix in the 0.9.0 release.

@GhostofGoes GhostofGoes self-assigned this Jul 20, 2022
@GhostofGoes
Copy link
Owner

Punting this to 1.0.0 release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants