Skip to content

Commit

Permalink
Use aux data in NativeCANSocket to determine timestamp of packet (#4208)
Browse files Browse the repository at this point in the history
* Use aux data in NativeCANSocket to determine timestamp of packet

* debug unit test

* fix unit test
  • Loading branch information
polybassa committed Jan 1, 2024
1 parent 0dd08cd commit f9c7d95
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
33 changes: 28 additions & 5 deletions scapy/contrib/cansocket_native.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand All @@ -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 = "<I%ds" % (len(pkt) - 4)
unpack_fmt = ">I%ds" % (len(pkt) - 4)
pkt = struct.pack(pack_fmt, *struct.unpack(unpack_fmt, pkt))
return self.basecls, pkt, get_last_packet_timestamp(self.ins)

if pkt and ts is None:
from scapy.arch.linux import get_last_packet_timestamp
ts = get_last_packet_timestamp(self.ins)

return self.basecls, pkt, ts

def send(self, x):
# type: (Packet) -> int
if x is None:
return 0

try:
x.sent_time = time.time()
except AttributeError:
Expand Down
2 changes: 1 addition & 1 deletion scapy/contrib/isotp/isotp_native_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion test/contrib/cansocket_native.uts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ sock1.close()

= sr can check rx and tx

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

Expand Down

0 comments on commit f9c7d95

Please sign in to comment.