From 8fcef413a2c9d600dcd0f9125727ab29f4b5bf49 Mon Sep 17 00:00:00 2001 From: Nils Weiss Date: Wed, 13 Dec 2023 21:39:50 +0100 Subject: [PATCH 1/3] Use aux data in NativeCANSocket to determine timestamp of packet --- scapy/contrib/cansocket_native.py | 33 ++++++++++++++++++---- scapy/contrib/isotp/isotp_native_socket.py | 2 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/scapy/contrib/cansocket_native.py b/scapy/contrib/cansocket_native.py index ba9ef0ff440..49efacd457c 100644 --- a/scapy/contrib/cansocket_native.py +++ b/scapy/contrib/cansocket_native.py @@ -15,11 +15,11 @@ import time from scapy.config import conf +from scapy.data import SO_TIMESTAMPNS from scapy.supersocket import SuperSocket -from scapy.error import Scapy_Exception, warning +from scapy.error import Scapy_Exception, warning, log_runtime from scapy.packet import Packet from scapy.layers.can import CAN, CAN_MTU, CAN_FD_MTU -from scapy.arch.linux import get_last_packet_timestamp from scapy.compat import raw from typing import ( @@ -84,6 +84,20 @@ def __init__(self, "Could not modify receive own messages (%s)", exception ) + try: + # Receive Auxiliary Data (Timestamps) + self.ins.setsockopt( + socket.SOL_SOCKET, + SO_TIMESTAMPNS, + 1 + ) + self.auxdata_available = True + except OSError: + # Note: Auxiliary Data is only supported since + # Linux 2.6.21 + msg = "Your Linux Kernel does not support Auxiliary Data!" + log_runtime.info(msg) + if self.fd: try: self.ins.setsockopt(socket.SOL_CAN_RAW, @@ -118,8 +132,9 @@ def recv_raw(self, x=CAN_MTU): # type: (int) -> Tuple[Optional[Type[Packet]], Optional[bytes], Optional[float]] # noqa: E501 """Returns a tuple containing (cls, pkt_data, time)""" pkt = None + ts = None try: - pkt = self.ins.recv(self.MTU) + pkt, _, ts = self._recv_raw(self.ins, self.MTU) except BlockingIOError: # noqa: F821 warning("Captured no data, socket in non-blocking mode.") except socket.timeout: @@ -130,14 +145,22 @@ def recv_raw(self, x=CAN_MTU): # need to change the byte order of the first four bytes, # required by the underlying Linux SocketCAN frame format - if not conf.contribs['CAN']['swap-bytes'] and pkt is not None: + if not conf.contribs['CAN']['swap-bytes'] and pkt: pack_fmt = " int + if x is None: + return 0 + try: x.sent_time = time.time() except AttributeError: diff --git a/scapy/contrib/isotp/isotp_native_socket.py b/scapy/contrib/isotp/isotp_native_socket.py index 7718365c954..127e91f6d0e 100644 --- a/scapy/contrib/isotp/isotp_native_socket.py +++ b/scapy/contrib/isotp/isotp_native_socket.py @@ -390,7 +390,7 @@ def recv_raw(self, x=0xffff): self.close() return None, None, None - if ts is None: + if pkt and ts is None: ts = get_last_packet_timestamp(self.ins) return self.basecls, pkt, ts From 8cac2cd7c4019fcabca426721cee6138344be8c2 Mon Sep 17 00:00:00 2001 From: Nils Weiss Date: Wed, 13 Dec 2023 22:00:34 +0100 Subject: [PATCH 2/3] debug unit test --- test/contrib/cansocket_native.uts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/contrib/cansocket_native.uts b/test/contrib/cansocket_native.uts index 22d48de1117..34b84cd52c5 100644 --- a/test/contrib/cansocket_native.uts +++ b/test/contrib/cansocket_native.uts @@ -140,7 +140,10 @@ sock1.close() = sr can check rx and tx -assert tx.sent_time > 0 and rx.time > 0 and tx.sent_time < rx.time +print(tx.sent_time) +print(rx.time) + +assert tx.sent_time > 0 and rx.time > 0 and tx.sent_time <= rx.time = sniff with filtermask 0x7ff From ff8886dc6f8f116bd017cc5c46e917034e489dab Mon Sep 17 00:00:00 2001 From: Nils Weiss Date: Wed, 13 Dec 2023 22:10:33 +0100 Subject: [PATCH 3/3] fix unit test --- test/contrib/cansocket_native.uts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/contrib/cansocket_native.uts b/test/contrib/cansocket_native.uts index 34b84cd52c5..fedf063eef6 100644 --- a/test/contrib/cansocket_native.uts +++ b/test/contrib/cansocket_native.uts @@ -140,10 +140,7 @@ sock1.close() = sr can check rx and tx -print(tx.sent_time) -print(rx.time) - -assert tx.sent_time > 0 and rx.time > 0 and tx.sent_time <= rx.time +assert tx.sent_time > 0 and rx.time > 0 = sniff with filtermask 0x7ff