secdev / secdev/scapy

psrc property of ARP packet returns invalid text instead of IP address in some cases

Open
#4,420 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs additional info
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.