psrc property of ARP packet returns invalid text instead of IP address in some cases
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 12.6k
- Forks
- 2.2k
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 56
Description
Brief description
Hey guys. We have been using the scapy library to parse the result of a tcpdump process in which we perform the arping function for quite a while now with success.
Until a few days ago it started behaving weird when printing the replies of a packet. We are interested in which IP address is being returned by some MAC address. To do so, we use the rdpcap module, loop over the sessions and get the packet[Ether].src for the MAC address and the packet[ARP].psrc for the IP address.
In some cases, the IP address contains some weird ASCII entries like b'\ns\x14g' or b'\ns\x14f'.
Is there something wrong with the way we parse the results from the ARP replies, or is something else wrong? Thanks in advance!
Scapy version
2.5.0
Python version
3.9.18
Operating system
Linux 5.14.0-427.13.1.el9_4.x86_64 (RHEL 10)
Additional environment information
No response
How to reproduce
The function to start the tcpdump process and the arping call:
def perform_arp_request(range, interface, pcap_filename):
# first start tcpdump process in the background
process = Popen(
['tcpdump', '-i', interface, '-w', pcap_filename, '-s', '65535', 'arp', 'and', 'arp[7]', '==', '2'],
stdout=DEVNULL,
stderr=DEVNULL
)
arping(range, iface=interface, verbose=False)
sleep(1)
process.terminate()
The function to parse the results from the tcpdump file:
def parse_and_print_results(pcap_filename):
data = set()
pcap_flow = rdpcap(pcap_filename)
sessions = pcap_flow.sessions()
for session in sessions:
for packet in sessions[session]:
data.add((packet[Ether].src, packet[ARP].psrc))
for mac, ip in data:
print(mac + ',' + ip)
Actual result
The following error is thrown:
TypeError: can only concatenate str (not "bytes") to str
It happens here:
print(mac + ',' + ip)
Because IP in this case is equal to b'\ns\x14h'. So it seems like the expected IP of 10.115.20.104 as seen from parsing the pcap file is evaluated to some weird string. Also note in the pcap file that for this case, there are 2 ARP replies from that IP. Don't know if it's related.
Expected result
00:50:56:95:e3:b3,10.115.20.7,
00:50:56:95:58:14,10.115.20.25
b4:96:91:4e:9c:c5,10.115.20.104
00:50:56:aa:da:db,10.115.20.22
00:50:56:95:73:c4,10.115.20.20
Related resources
13:50:15.471285 ARP, Reply 10.115.20.7 is-at 00:50:56:95:e3:b3 (oui Unknown), length 46
13:50:15.474909 ARP, Reply 10.115.20.25 is-at 00:50:56:95:58:14 (oui Unknown), length 46
13:50:15.489031 ARP, Reply 10.115.20.104 is-at b4:96:91:4e:9c:c5 (oui Unknown), length 46
13:50:15.489031 ARP, Reply 10.115.20.104 is-at b4:96:91:4e:9c:c5 (oui Unknown), length 46
13:50:15.475548 ARP, Reply 10.115.20.22 is-at 00:50:56:aa:da:db (oui Unknown), length 46
13:50:15.474909 ARP, Reply 10.115.20.25 is-at 00:50:56:95:58:14 (oui Unknown), length 46
Debug script
Run this script with a pcap file as argument (e.g. python3 scapy_debug.py some_dump.pcap)
import sys
from scapy.layers.l2 import arping, Ether, ARP
from scapy.utils import rdpcap
def parse_and_print_results(pcap_filename):
data = set()
pcap_flow = rdpcap(pcap_filename)
sessions = pcap_flow.sessions()
for session in sessions:
for packet in sessions[session]:
data.add((packet[Ether].src, packet[ARP].psrc))
for mac, ip in data:
try:
print(mac + ',' + ip)
except:
print('---- ERROR ----')
print(ip)
print(mac)
print('---------------')
if __name__ == "__main__":
parse_and_print_results(sys.argv[1])
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided debug script against an affected pcap, then inspect ARP.psrc in scapy.layers.l2 and how rdpcap loads the packets. Compare the raw ARP replies with the values exposed by packet[ARP].psrc. Done means the cause of the byte-valued address is established and the expected IP text is reliably produced or the limitation is clearly documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100