def write_car_event_to_can_packet(car: Vehicle, event_list: CarEvent):
    pkt_list = []
    for event in event_list:
        if event.ID == CarEvent.CAR_EVENT_FREE:
            continue
        data = car.dbc_data.simple_msg_encode(event.ID, event.value)

        # extend to 8 bytes by padding zero
        data = data + '00' * (8 -
                              car.dbc_data.get_msg_length_in_byte(event.ID))

        byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7 = \
            int(data[0:2], 16), \
            int(data[2:4], 16), \
            int(data[4:6], 16), \
            int(data[6:8], 16), \
            int(data[8:10], 16), \
            int(data[10:12], 16), \
            int(data[12:14], 16), \
            int(data[14:], 16)

        can_payload = \
            struct.pack('<8B', byte0, byte1, byte2, byte3,
                        byte4, byte5, byte6, byte7)
        pkt = CAN(identifier=event.ID, length=len(data), data=can_payload)
        pkt.time = event.timestamp
        pkt_list.append(pkt)

    wrpcap("can_packet.pcap", pkt_list)
    return
Пример #2
0
 def can_send(self, load):
     # type: (bytes) -> None
     if self.padding:
         load += b"\xCC" * (CAN_MAX_DLEN - len(load))
     if self.tx_id is None or self.tx_id <= 0x7ff:
         self.can_socket.send(CAN(identifier=self.tx_id, data=load))
     else:
         self.can_socket.send(
             CAN(identifier=self.tx_id, flags="extended", data=load))
Пример #3
0
 def recv(self):
     msg = self.iface.recv(timeout=1)
     if msg is None:
         raise CANSocketTimeoutElapsed
     frame = CAN(identifier=msg.arbitration_id,
                 length=msg.dlc,
                 data=bytes(msg.data))
     if msg.is_error_frame:
         frame.flags |= 0x1
     if msg.is_remote_frame:
         frame.flags |= 0x2
     if msg.is_extended_id:
         frame.flags |= 0x4
     frame.time = msg.timestamp
     return frame
Пример #4
0
 def recv(self):
     msg = self.iface.recv(timeout=1)
     if msg is None:
         raise CANSocketTimeoutElapsed
     frame = CAN(identifier=msg.arbitration_id,
                 length=msg.dlc,
                 data=bytes(msg.data))
     if msg.is_error_frame:
         frame.flags |= 0x1
     if msg.is_remote_frame:
         frame.flags |= 0x2
     if msg.is_extended_id:
         frame.flags |= 0x4
     frame.time = msg.timestamp
     return frame
Пример #5
0
    def fragment(self):
        data_bytes_in_frame = 7
        if self.exdst is not None:
            data_bytes_in_frame = 6

        if len(self.data) > ISOTP_MAX_DLEN_2015:
            raise Scapy_Exception("Too much data in ISOTP message")

        if len(self.data) <= data_bytes_in_frame:
            # We can do this in a single frame
            frame_data = struct.pack('B', len(self.data)) + self.data
            if self.exdst:
                frame_data = struct.pack('B', self.exdst) + frame_data
            pkt = CAN(identifier=self.dst, data=frame_data)
            return [pkt]

        # Construct the first frame
        if len(self.data) <= ISOTP_MAX_DLEN:
            frame_header = struct.pack(">H", len(self.data) + 0x1000)
        else:
            frame_header = struct.pack(">HI", 0x1000, len(self.data))
        if self.exdst:
            frame_header = struct.pack('B', self.exdst) + frame_header
        idx = 8 - len(frame_header)
        frame_data = self.data[0:idx]
        frame = CAN(identifier=self.dst, data=frame_header + frame_data)

        # Construct consecutive frames
        n = 1
        pkts = [frame]
        while idx < len(self.data):
            frame_data = self.data[idx:idx + data_bytes_in_frame]
            frame_header = struct.pack("b", (n % 16) + N_PCI_CF)

            n += 1
            idx += len(frame_data)

            if self.exdst:
                frame_header = struct.pack('B', self.exdst) + frame_header
            pkt = CAN(identifier=self.dst, data=frame_header + frame_data)
            pkts.append(pkt)
        return pkts
Пример #6
0
    def recv(self, x=CAN_FRAME_SIZE):
        try:
            pkt, sa_ll = self.ins.recvfrom(x)
        except BlockingIOError:  # noqa: F821
            warning("Captured no data, socket in non-blocking mode.")
            return None
        except socket.timeout:
            warning("Captured no data, socket read timed out.")
            return None
        except OSError:
            # something bad happened (e.g. the interface went down)
            warning("Captured no data.")
            return None

        # need to change the byteoder of the first four bytes,
        # required by the underlying Linux SocketCAN frame format
        pkt = struct.pack("<I12s", *struct.unpack(">I12s", pkt))
        len = pkt[4]
        canpkt = CAN(pkt[:len + 8])
        canpkt.time = get_last_packet_timestamp(self.ins)
        if self.remove_padding:
            return canpkt
        else:
            return canpkt / Padding(pkt[len + 8:])
Пример #7
0
    def recv(self, x=CAN_FRAME_SIZE):
        try:
            pkt, sa_ll = self.ins.recvfrom(x)
        except BlockingIOError:  # noqa: F821
            warning("Captured no data, socket in non-blocking mode.")
            return None
        except socket.timeout:
            warning("Captured no data, socket read timed out.")
            return None
        except OSError:
            # something bad happened (e.g. the interface went down)
            warning("Captured no data.")
            return None

        # need to change the byteoder of the first four bytes,
        # required by the underlaying Linux SocketCAN frame format
        pkt = struct.pack("<I12s", *struct.unpack(">I12s", pkt))
        len = pkt[4]
        canpkt = CAN(pkt[:len + 8])
        canpkt.time = get_last_packet_timestamp(self.ins)
        if self.remove_padding:
            return canpkt
        else:
            return canpkt / Padding(pkt[len + 8:])
Пример #8
0
if args.extended_only:
    extended_only = True
if args.k:
    keep_awake = True
    awake_interface = args.k

# Dictionary with Send-to-ID as key and a tuple (received packet, Recv_ID)
found_packets = {}
# List with paket-IDs of background noise packets
noise_IDs = []
# Seconds to listen to noise
noise_listen_time = 10
# Number of pakets send in a single blow
extended_load = 100

dummy_pkt = CAN(identifier=0x123, data=b'\xaa\xbb\xcc\xdd\xee\xff\xaa\xbb')

# Interface for communication
CanSocket_communication = CANSocket(scan_interface)

# Keep ECU awake
if keep_awake:
    CanSocket_keep_awake = CANSocket(awake_interface)
    awake_thread = isotpscan.KeepAwakeThread(CanSocket_keep_awake, dummy_pkt)
    awake_thread.start()

# Listen for default messages on CAN-bus
print("Filtering background noise...")
CanSocket_communication.sniff(
    prn=get_background_noise_callback,
    timeout=noise_listen_time,
Пример #9
0
def isotp_scan(
        sock,  # type: SuperSocket
        scan_range=range(0x7ff + 1),  # type: Iterable[int]
        extended_addressing=False,  # type: bool
        extended_scan_range=range(0x100),  # type: Iterable[int]
        noise_listen_time=2,  # type: int
        sniff_time=0.1,  # type: float
        output_format=None,  # type: Optional[str]
        can_interface=None,  # type: Optional[str]
        extended_can_id=False,  # type: bool
        verbose=False  # type: bool
):
    # type: (...) -> Union[str, List[SuperSocket]]
    """Scan for ISOTP Sockets on a bus and return findings

    Scan for ISOTP Sockets in the defined range and returns found sockets
    in a specified format. The format can be:

    - text: human readable output
    - code: python code for copy&paste
    - sockets: if output format is not specified, ISOTPSockets will be
      created and returned in a list

    :param sock: CANSocket object to communicate with the bus under scan
    :param scan_range: range of CAN-Identifiers to scan. Default is 0x0 - 0x7ff
    :param extended_addressing: scan with ISOTP extended addressing
    :param extended_scan_range: range for ISOTP extended addressing values
    :param noise_listen_time: seconds to listen for default communication on
                              the bus
    :param sniff_time: time the scan waits for isotp flow control responses
                       after sending a first frame
    :param output_format: defines the format of the returned results
                          (text, code or sockets). Provide a string e.g.
                          "text". Default is "socket".
    :param can_interface: interface used to create the returned code/sockets
    :param extended_can_id: Use Extended CAN-Frames
    :param verbose: displays information during scan
    :return:
    """
    if verbose:
        print("Filtering background noise...")

    # Send dummy packet. In most cases, this triggers activity on the bus.

    dummy_pkt = CAN(identifier=0x123, data=b'\xaa\xbb\xcc\xdd\xee\xff\xaa\xbb')

    background_pkts = sock.sniff(timeout=noise_listen_time,
                                 started_callback=lambda: sock.send(dummy_pkt))

    noise_ids = list(set(pkt.identifier for pkt in background_pkts))

    if extended_addressing:
        found_packets = scan_extended(sock,
                                      scan_range,
                                      extended_scan_range=extended_scan_range,
                                      noise_ids=noise_ids,
                                      sniff_time=sniff_time,
                                      extended_can_id=extended_can_id,
                                      verbose=verbose)
    else:
        found_packets = scan(sock,
                             scan_range,
                             noise_ids=noise_ids,
                             sniff_time=sniff_time,
                             extended_can_id=extended_can_id,
                             verbose=verbose)

    filter_periodic_packets(found_packets, verbose)

    if output_format == "text":
        return generate_text_output(found_packets, extended_addressing)

    if output_format == "code":
        return generate_code_output(found_packets, can_interface,
                                    extended_addressing)

    return generate_isotp_list(found_packets, can_interface or sock,
                               extended_addressing)
Пример #10
0
 def can_send(load):
     can_socket.send(CAN(identifier=sid, data=load))
Пример #11
0
    def fragment(self, *args, **kargs):
        # type: (*Any, **Any) -> List[Packet]
        """Helper function to fragment an ISOTP message into multiple
        CAN frames.

        :return: A list of CAN frames
        """
        data_bytes_in_frame = 7
        if self.rx_ext_address is not None:
            data_bytes_in_frame = 6

        if len(self.data) > ISOTP_MAX_DLEN_2015:
            raise Scapy_Exception("Too much data in ISOTP message")

        if len(self.data) <= data_bytes_in_frame:
            # We can do this in a single frame
            frame_data = struct.pack('B', len(self.data)) + self.data
            if self.rx_ext_address:
                frame_data = struct.pack('B', self.rx_ext_address) + frame_data

            if self.rx_id is None or self.rx_id <= 0x7ff:
                pkt = CAN(identifier=self.rx_id, data=frame_data)
            else:
                pkt = CAN(identifier=self.rx_id, flags="extended",
                          data=frame_data)
            return [pkt]

        # Construct the first frame
        if len(self.data) <= ISOTP_MAX_DLEN:
            frame_header = struct.pack(">H", len(self.data) + 0x1000)
        else:
            frame_header = struct.pack(">HI", 0x1000, len(self.data))
        if self.rx_ext_address:
            frame_header = struct.pack('B', self.rx_ext_address) + frame_header
        idx = 8 - len(frame_header)
        frame_data = self.data[0:idx]
        if self.rx_id is None or self.rx_id <= 0x7ff:
            frame = CAN(identifier=self.rx_id, data=frame_header + frame_data)
        else:
            frame = CAN(identifier=self.rx_id, flags="extended",
                        data=frame_header + frame_data)

        # Construct consecutive frames
        n = 1
        pkts = [frame]
        while idx < len(self.data):
            frame_data = self.data[idx:idx + data_bytes_in_frame]
            frame_header = struct.pack("b", (n % 16) + N_PCI_CF)

            n += 1
            idx += len(frame_data)

            if self.rx_ext_address:
                frame_header = struct.pack('B', self.rx_ext_address) + frame_header  # noqa: E501
            if self.rx_id is None or self.rx_id <= 0x7ff:
                pkt = CAN(identifier=self.rx_id, data=frame_header + frame_data)  # noqa: E501
            else:
                pkt = CAN(identifier=self.rx_id, flags="extended",
                          data=frame_header + frame_data)
            pkts.append(pkt)
        return pkts
Пример #12
0
# CAN-ID Range
min_ID = int(sys.argv[1], 16)
max_ID = int(sys.argv[2], 16)

# Get arguments
args = []
for i in range(0, len(sys.argv)):
    args.append(sys.argv[i])
if "-e" in args:
    extended = True
if "-k" in args:
    awake_interface = True
if "-eo" in args:
    extended_only = True

dummy_pkt = CAN(identifier=0x123, data=b'\xaa\xff\xff\xff\xff\xff\xff\xee')

# Interface
CanSocket_communication = CANSocket("can1")

# Keep ECU awake
if awake_interface:
    CanSocket_keep_awake = CANSocket("can0")
    awake_thread = keep_awake_thread(dummy_pkt)
    awake_thread.start()

# Listen for default messages on CAN-bus
print("Filtering background noise...")
CanSocket_communication.sniff(prn=get_background_noise,
                              timeout=noise_listen_time,
                              started_callback=lambda: