Skip to content

Packet Timestamps being overwritten - Identified a Solution #2423

@rwhalb

Description

@rwhalb

Brief description

I have installed the latest commit of scapy with the "Rework Timestamp Detection" commit:
#2401

I have determined that the packet received timestamp is being overwritten.

Environment

  • Scapy version: v2.4.3-237.g90c8d820
  • Python version: e.g. 3.7
  • Operating System: e.g. Fedora 30 (NST 30)

How to reproduce

Use the following script to send four (4) TCP sync packets to your default gateway. On a typical LAN you should get sub-milliseconds round-trip-time results. Substitute your default gateway for the 'dest' variable.

#
# Scapy script to compute Round Trip Times (rrt)...
from scapy.all import *

dest = "Your Gateway IPv4 Address"

pkt = []
pkt_rst = []
for i in range(1, 5):
    a = IP(dst=dest) / TCP(flags="S", seq=i, sport=65000+i, dport=55556)
    b = IP(dst=dest) / TCP(flags="R", seq=i, sport=65000+i, dport=55556)
    pkt.append(a)
    pkt_rst.append(b)

ans, unans = sr(pkt, filter="host {0}".format(dest), inter=0, timeout=1)
send(pkt_rst, inter=0)

print("scapy version: {}".format(conf.version))

for pkt in ans:
    sent = pkt[0]
    received = pkt[1]
    res = (received.time - sent.sent_time) * 1000
    print(res)
    if res < 0:
        breakpoint()

Actual result

My source address: 10.222.222.10 (shopper2) and my gateway: 10.222.222.1:

[root@shopper2 opt]# python3 ./rrt-scapy.py 
Begin emission:
Finished sending 4 packets.

Received 5 packets, got 4 answers, remaining 0 packets
....
Sent 4 packets.
scapy version: v2.4.3-237.g90c8d820
9.302377700805664
7.546901702880859
5.416631698608398
3.2846927642822266
[root@shopper2 opt]#

As you can see the round-trip-times are way to big.

The Problem Area and Solution

After much debugging I found that the received packet was being overwritten in the "L3PacketSocket" class. Normally I would submit a Pull Request. But in this case I am only solving for the Linux platform and I am uncertain if the fix will be the permanent solution.

In file "arch/linux.py" I have preserved the received timestamp before assigning the "pkt" with the "pkt.payload" value:

Before:

class L3PacketSocket(L2Socket):
    desc = "read/write packets at layer 3 using Linux PF_PACKET sockets"

    def recv(self, x=MTU):
        pkt = SuperSocket.recv(self, x)
        if pkt and self.lvl == 2:
            pkt = pkt.payload
        return pkt

After:

class L3PacketSocket(L2Socket):
    desc = "read/write packets at layer 3 using Linux PF_PACKET sockets"

    def recv(self, x=MTU):
        pkt = SuperSocket.recv(self, x)
        if pkt and self.lvl == 2:
            ts = pkt.time
            pkt = pkt.payload
            pkt.time = ts
        return pkt

Suggestion: The "pkt.time" may could be renamed to "pkt.recv_time"

Expected result

After the modification is in place the following are the results:

[root@shopper2 opt]# python3 ./rrt-scapy.py 
Begin emission:
Finished sending 4 packets.

Received 5 packets, got 4 answers, remaining 0 packets
....
Sent 4 packets.
scapy version: v2.4.3-237.g90c8d820
0.43010711669921875
0.34427642822265625
0.28777122497558594
0.2853870391845703
[root@shopper2 opt]#

Now sub-millisecond round-trip-times are measured using TCP Sync packets. To verify lets do a ping to the gateway (10.222.222.1):

[root@shopper2 opt]# ping -c 4 -nv 10.222.222.1
PING 10.222.222.1 (10.222.222.1) 56(84) bytes of data.
64 bytes from 10.222.222.1: icmp_seq=1 ttl=64 time=0.413 ms
64 bytes from 10.222.222.1: icmp_seq=2 ttl=64 time=0.327 ms
64 bytes from 10.222.222.1: icmp_seq=3 ttl=64 time=0.339 ms
64 bytes from 10.222.222.1: icmp_seq=4 ttl=64 time=0.331 ms

--- 10.222.222.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 100ms
rtt min/avg/max/mdev = 0.327/0.352/0.413/0.039 ms
[root@shopper2 opt]# 

As you can see the ICMP round-trip-time results agree nicely with the TCP Sync packets.

Scapy Multi-Traceroute Add On: mtraceroute

I will be announcing this scapy Multi-Traceroute add on feature: mtraceroute once we get the packet timestamps corrected.

---Ron Henderson
CoAuthor of NST (Network Security Toolkit)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions