mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-18 20:03:47 +00:00
Initial import of the isotp:// plugin ##io
This commit is contained in:
parent
c539afaa07
commit
4d2be3830f
1
dist/plugins-cfg/plugins.def.cfg
vendored
1
dist/plugins-cfg/plugins.def.cfg
vendored
@ -271,6 +271,7 @@ io.zip
|
||||
io.r2k
|
||||
io.ar
|
||||
io.fd
|
||||
io.isotp
|
||||
io.rbuf
|
||||
lang.c
|
||||
lang.v
|
||||
|
@ -525,6 +525,7 @@ extern RIOPlugin r_io_plugin_winedbg;
|
||||
extern RIOPlugin r_io_plugin_gprobe;
|
||||
extern RIOPlugin r_io_plugin_fd;
|
||||
extern RIOPlugin r_io_plugin_socket;
|
||||
extern RIOPlugin r_io_plugin_isotp;
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ typedef struct r_socket_http_options {
|
||||
|
||||
#define R_SOCKET_PROTO_TCP IPPROTO_TCP
|
||||
#define R_SOCKET_PROTO_UDP IPPROTO_UDP
|
||||
#define R_SOCKET_PROTO_CAN 0xc42b05
|
||||
#define R_SOCKET_PROTO_UNIX 0x1337
|
||||
#define R_SOCKET_PROTO_NONE 0
|
||||
#define R_SOCKET_PROTO_DEFAULT R_SOCKET_PROTO_TCP
|
||||
|
@ -71,6 +71,7 @@ endif
|
||||
if host_machine.system() == 'linux' or host_machine.system() == 'android'
|
||||
r_io_sources += [
|
||||
'p/io_r2k_linux.c',
|
||||
'p/io_isotp.c',
|
||||
]
|
||||
## only for shm_open
|
||||
# r_io_deps += meson.get_compiler('c').find_library('rt')
|
||||
|
@ -15,7 +15,7 @@ endif
|
||||
all: ${ALL_TARGETS}
|
||||
|
||||
ALL_TARGETS=
|
||||
PLUGINS=ptrace.mk debug.mk gdb.mk malloc.mk shm.mk mach.mk w32dbg.mk procpid.mk winkd.mk bochs.mk qnx.mk r2k.mk ar.mk rbuf.mk gprobe.mk
|
||||
PLUGINS=ptrace.mk debug.mk gdb.mk malloc.mk shm.mk mach.mk w32dbg.mk procpid.mk winkd.mk bochs.mk qnx.mk r2k.mk ar.mk rbuf.mk gprobe.mk isotp.mk
|
||||
#zip.mk
|
||||
#PLUGINS=ptrace.mk debug.mk gdb.mk malloc.mk mach.mk w32dbg.mk procpid.mk
|
||||
include ${PLUGINS}
|
||||
|
156
libr/io/p/io_isotp.c
Normal file
156
libr/io/p/io_isotp.c
Normal file
@ -0,0 +1,156 @@
|
||||
/* radare - LGPL - Copyright 2021 - pancake */
|
||||
|
||||
#include <r_io.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_cons.h>
|
||||
|
||||
#if __linux__
|
||||
|
||||
#include "../io_memory.h"
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/raw.h>
|
||||
|
||||
#define ISOTPURI "isotp://"
|
||||
|
||||
typedef struct {
|
||||
RSocket *sc;
|
||||
int count;
|
||||
} RIOSocketData;
|
||||
|
||||
static void free_socketdata(RIOSocketData *sd) {
|
||||
if (sd) {
|
||||
r_socket_free (sd->sc);
|
||||
free (sd);
|
||||
}
|
||||
}
|
||||
|
||||
static int __write(RIO *io, RIODesc *desc, const ut8 *buf, int count) {
|
||||
RIOMalloc *mal = (RIOMalloc*)desc->data;
|
||||
if (mal) {
|
||||
r_cons_break_push (NULL, NULL);
|
||||
RSocket *s = ((RIOSocketData*)(mal->data))->sc;
|
||||
return r_socket_write (s, buf, count);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __read(RIO *io, RIODesc *desc, ut8 *buf, int count) {
|
||||
RIOMalloc *mal = (RIOMalloc*)desc->data;
|
||||
if (mal) {
|
||||
ut64 addr = mal->offset;
|
||||
r_cons_break_push (NULL, NULL);
|
||||
RIOSocketData *sdat = mal->data;
|
||||
RSocket *s = sdat->sc;
|
||||
ut8 *mem = malloc (4096);
|
||||
if (mem) {
|
||||
int c = r_socket_read (s, mem, 4096);
|
||||
if (c > 0) {
|
||||
int osz = mal->size;
|
||||
io_memory_resize (io, desc, mal->size + c);
|
||||
memcpy (mal->buf + osz, mem, c);
|
||||
io->corebind.cmdf (io->corebind.core, "f nread_%d %d %d",
|
||||
sdat->count, c, mal->size);
|
||||
io->corebind.cmdf (io->corebind.core, "omr 1 %d", mal->size);
|
||||
sdat->count++;
|
||||
}
|
||||
free (mem);
|
||||
}
|
||||
r_cons_break_pop ();
|
||||
mal->offset = addr;
|
||||
return io_memory_read (io, desc, buf, count);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __close(RIODesc *desc) {
|
||||
R_FREE (desc->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool __check(RIO *io, const char *pathname, bool many) {
|
||||
return !strncmp (pathname, ISOTPURI, strlen (ISOTPURI));
|
||||
}
|
||||
|
||||
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||
if (r_sandbox_enable (false)) {
|
||||
eprintf ("The " ISOTPURI " uri is not permitted in sandbox mode.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!__check (io, pathname, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
RIOMalloc *mal = R_NEW0 (RIOMalloc);
|
||||
if (!mal) {
|
||||
return NULL;
|
||||
}
|
||||
RIOSocketData *data = R_NEW0 (RIOSocketData);
|
||||
if (!mal || !data) {
|
||||
free (mal);
|
||||
free_socketdata (data);
|
||||
return NULL;
|
||||
}
|
||||
mal->data = data;
|
||||
mal->buf = calloc (1, 1);
|
||||
if (!mal->buf) {
|
||||
free (mal);
|
||||
free_socketdata (data);
|
||||
return NULL;
|
||||
}
|
||||
mal->size = 1;
|
||||
mal->offset = 0;
|
||||
pathname += strlen (ISOTPURI);
|
||||
|
||||
if (*pathname == '?') {
|
||||
eprintf ("Usage: r2 isotp://interface/source/destination\n");
|
||||
} else {
|
||||
char *host = strdup (pathname);
|
||||
const char *port = "";
|
||||
char *slash = strchr (host, '/');
|
||||
if (slash) {
|
||||
*slash = 0;
|
||||
port = slash + 1;
|
||||
}
|
||||
data->sc = r_socket_new (false);
|
||||
if (!r_socket_connect (data->sc, host, port, R_SOCKET_PROTO_CAN, 0)) {
|
||||
eprintf ("Cannot connect\n");
|
||||
free (host);
|
||||
free_socketdata (data);
|
||||
return NULL;
|
||||
}
|
||||
r_socket_block_time (data->sc, false, 0, 0);
|
||||
free (host);
|
||||
}
|
||||
return r_io_desc_new (io, &r_io_plugin_isotp, pathname, R_PERM_RW | rw, mode, mal);
|
||||
}
|
||||
|
||||
RIOPlugin r_io_plugin_isotp = {
|
||||
.name = "isotp",
|
||||
.desc = "Connect using the ISOTP protocol (isotp://interface/srcid/dstid)",
|
||||
.uris = ISOTPURI,
|
||||
.license = "MIT",
|
||||
.open = __open,
|
||||
.close = __close,
|
||||
.read = __read,
|
||||
.seek = io_memory_lseek,
|
||||
.check = __check,
|
||||
.write = __write,
|
||||
};
|
||||
|
||||
#else
|
||||
RIOPlugin r_io_plugin_isotp = {
|
||||
.name = "isotp",
|
||||
.desc = "shared memory resources (not for this platform)",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef R2_PLUGIN_INCORE
|
||||
R_API RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_IO,
|
||||
.data = &r_io_plugin_isotp,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
@ -144,7 +144,7 @@ RIOPlugin r_io_plugin_shm = {
|
||||
#else
|
||||
RIOPlugin r_io_plugin_shm = {
|
||||
.name = "shm",
|
||||
.desc = "shared memory resources (not for w32)",
|
||||
.desc = "shared memory resources (not for this platform)",
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -93,7 +93,7 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) {
|
||||
}
|
||||
mal->size = 1;
|
||||
mal->offset = 0;
|
||||
pathname += strlen ("socket://");
|
||||
pathname += strlen (SOCKETURI);
|
||||
|
||||
if (*pathname == '?') {
|
||||
eprintf ("Usage: $ nc -l -p 9999 ; r2 socket://localhost:9999\n");
|
||||
|
17
libr/io/p/isotp.mk
Normal file
17
libr/io/p/isotp.mk
Normal file
@ -0,0 +1,17 @@
|
||||
OBJ_ISOTP=io_isotp.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_ISOTP}
|
||||
TARGET_ISOTP=io_isotp.${EXT_SO}
|
||||
ALL_TARGETS+=${TARGET_ISOTP}
|
||||
|
||||
ifeq (${WITHPIC},0)
|
||||
LINKFLAGS+=../../util/libr_util.a
|
||||
LINKFLAGS+=../../io/libr_io.a
|
||||
else
|
||||
LINKFLAGS+=-L../../util -lr_util
|
||||
LINKFLAGS+=-L.. -lr_io
|
||||
endif
|
||||
|
||||
${TARGET_ISOTP}: ${OBJ_ISOTP}
|
||||
${CC_LIB} $(call libname,io_isotp) ${CFLAGS} -o ${TARGET_ISOTP} \
|
||||
${LDFLAGS} ${OBJ_ISOTP} ${LINKFLAGS}
|
228
libr/socket/i/can.h
Normal file
228
libr/socket/i/can.h
Normal file
@ -0,0 +1,228 @@
|
||||
/* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
/*
|
||||
* linux/can.h
|
||||
*
|
||||
* Definitions for CAN network layer (socket addr / CAN frame / CAN filter)
|
||||
*
|
||||
* Authors: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
|
||||
* Urs Thuermann <urs.thuermann@volkswagen.de>
|
||||
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Volkswagen nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* Alternatively, provided that this notice is retained in full, this
|
||||
* software may be distributed under the terms of the GNU General
|
||||
* Public License ("GPL") version 2, in which case the provisions of the
|
||||
* GPL apply INSTEAD OF those given above.
|
||||
*
|
||||
* The provided data structures and external interfaces from this code
|
||||
* are not restricted to be used by modules with a GPL compatible license.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _CAN_H
|
||||
#define _CAN_H
|
||||
|
||||
#if 0
|
||||
#include <linux/types.h>
|
||||
#include <linux/socket.h>
|
||||
#else
|
||||
#define __u8 unsigned char
|
||||
#define __u16 unsigned short
|
||||
#define __u32 unsigned int
|
||||
#define __u64 unsigned long long
|
||||
#define __kernel_sa_family_t unsigned short
|
||||
#endif
|
||||
|
||||
/* controller area network (CAN) kernel definitions */
|
||||
|
||||
/* special address description flags for the CAN_ID */
|
||||
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
|
||||
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
|
||||
#define CAN_ERR_FLAG 0x20000000U /* error message frame */
|
||||
|
||||
/* valid bits in CAN ID for frame formats */
|
||||
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
|
||||
#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
|
||||
#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
|
||||
|
||||
/*
|
||||
* Controller Area Network Identifier structure
|
||||
*
|
||||
* bit 0-28 : CAN identifier (11/29 bit)
|
||||
* bit 29 : error message frame flag (0 = data frame, 1 = error message)
|
||||
* bit 30 : remote transmission request flag (1 = rtr frame)
|
||||
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
|
||||
*/
|
||||
typedef __u32 canid_t;
|
||||
|
||||
#define CAN_SFF_ID_BITS 11
|
||||
#define CAN_EFF_ID_BITS 29
|
||||
|
||||
/*
|
||||
* Controller Area Network Error Message Frame Mask structure
|
||||
*
|
||||
* bit 0-28 : error class mask (see include/uapi/linux/can/error.h)
|
||||
* bit 29-31 : set to zero
|
||||
*/
|
||||
typedef __u32 can_err_mask_t;
|
||||
|
||||
/* CAN payload length and DLC definitions according to ISO 11898-1 */
|
||||
#define CAN_MAX_DLC 8
|
||||
#define CAN_MAX_DLEN 8
|
||||
|
||||
/* CAN FD payload length and DLC definitions according to ISO 11898-7 */
|
||||
#define CANFD_MAX_DLC 15
|
||||
#define CANFD_MAX_DLEN 64
|
||||
|
||||
/**
|
||||
* struct can_frame - basic CAN frame structure
|
||||
* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
|
||||
* @can_dlc: frame payload length in byte (0 .. 8) aka data length code
|
||||
* N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
|
||||
* mapping of the 'data length code' to the real payload length
|
||||
* @__pad: padding
|
||||
* @__res0: reserved / padding
|
||||
* @__res1: reserved / padding
|
||||
* @data: CAN frame payload (up to 8 byte)
|
||||
*/
|
||||
struct can_frame {
|
||||
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
|
||||
__u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
|
||||
__u8 __pad; /* padding */
|
||||
__u8 __res0; /* reserved / padding */
|
||||
__u8 __res1; /* reserved / padding */
|
||||
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
/*
|
||||
* defined bits for canfd_frame.flags
|
||||
*
|
||||
* The use of struct canfd_frame implies the Extended Data Length (EDL) bit to
|
||||
* be set in the CAN frame bitstream on the wire. The EDL bit switch turns
|
||||
* the CAN controllers bitstream processor into the CAN FD mode which creates
|
||||
* two new options within the CAN FD frame specification:
|
||||
*
|
||||
* Bit Rate Switch - to indicate a second bitrate is/was used for the payload
|
||||
* Error State Indicator - represents the error state of the transmitting node
|
||||
*
|
||||
* As the CANFD_ESI bit is internally generated by the transmitting CAN
|
||||
* controller only the CANFD_BRS bit is relevant for real CAN controllers when
|
||||
* building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make
|
||||
* sense for virtual CAN interfaces to test applications with echoed frames.
|
||||
*/
|
||||
#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
|
||||
#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
|
||||
|
||||
/**
|
||||
* struct canfd_frame - CAN flexible data rate frame structure
|
||||
* @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
|
||||
* @len: frame payload length in byte (0 .. CANFD_MAX_DLEN)
|
||||
* @flags: additional flags for CAN FD
|
||||
* @__res0: reserved / padding
|
||||
* @__res1: reserved / padding
|
||||
* @data: CAN FD frame payload (up to CANFD_MAX_DLEN byte)
|
||||
*/
|
||||
struct canfd_frame {
|
||||
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
|
||||
__u8 len; /* frame payload length in byte */
|
||||
__u8 flags; /* additional flags for CAN FD */
|
||||
__u8 __res0; /* reserved / padding */
|
||||
__u8 __res1; /* reserved / padding */
|
||||
__u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
#define CAN_MTU (sizeof(struct can_frame))
|
||||
#define CANFD_MTU (sizeof(struct canfd_frame))
|
||||
|
||||
/* particular protocols of the protocol family PF_CAN */
|
||||
#define CAN_RAW 1 /* RAW sockets */
|
||||
#define CAN_BCM 2 /* Broadcast Manager */
|
||||
#define CAN_TP16 3 /* VAG Transport Protocol v1.6 */
|
||||
#define CAN_TP20 4 /* VAG Transport Protocol v2.0 */
|
||||
#define CAN_MCNET 5 /* Bosch MCNet */
|
||||
#define CAN_ISOTP 6 /* ISO 15765-2 Transport Protocol */
|
||||
#define CAN_J1939 7 /* SAE J1939 */
|
||||
#define CAN_NPROTO 8
|
||||
|
||||
#define SOL_CAN_BASE 100
|
||||
|
||||
/**
|
||||
* struct sockaddr_can - the sockaddr structure for CAN sockets
|
||||
* @can_family: address family number AF_CAN.
|
||||
* @can_ifindex: CAN network interface index.
|
||||
* @can_addr: protocol specific address information
|
||||
*/
|
||||
struct sockaddr_can {
|
||||
__kernel_sa_family_t can_family;
|
||||
int can_ifindex;
|
||||
union {
|
||||
/* transport protocol class address information (e.g. ISOTP) */
|
||||
struct { canid_t rx_id, tx_id; } tp;
|
||||
|
||||
/* J1939 address information */
|
||||
struct {
|
||||
/* 8 byte name when using dynamic addressing */
|
||||
__u64 name;
|
||||
|
||||
/* pgn:
|
||||
* 8 bit: PS in PDU2 case, else 0
|
||||
* 8 bit: PF
|
||||
* 1 bit: DP
|
||||
* 1 bit: reserved
|
||||
*/
|
||||
__u32 pgn;
|
||||
|
||||
/* 1 byte address */
|
||||
__u8 addr;
|
||||
} j1939;
|
||||
|
||||
/* reserved for future CAN protocols address information */
|
||||
} can_addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct can_filter - CAN ID based filter in can_register().
|
||||
* @can_id: relevant bits of CAN ID which are not masked out.
|
||||
* @can_mask: CAN mask (see description)
|
||||
*
|
||||
* Description:
|
||||
* A filter matches, when
|
||||
*
|
||||
* <received_can_id> & mask == can_id & mask
|
||||
*
|
||||
* The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
|
||||
* filter for error message frames (CAN_ERR_FLAG bit set in mask).
|
||||
*/
|
||||
struct can_filter {
|
||||
canid_t can_id;
|
||||
canid_t can_mask;
|
||||
};
|
||||
|
||||
#define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
|
||||
#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
|
||||
|
||||
#endif /* !_UAPI_CAN_H */
|
130
libr/socket/i/isotp.h
Normal file
130
libr/socket/i/isotp.h
Normal file
@ -0,0 +1,130 @@
|
||||
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
/*
|
||||
* socketcan/can/isotp.h
|
||||
*
|
||||
* Definitions for isotp CAN sockets
|
||||
*
|
||||
* Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
|
||||
* Copyright (c) 2008 Volkswagen Group Electronic Research
|
||||
* All rights reserved.
|
||||
*
|
||||
* Send feedback to <socketcan-users@lists.berlios.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CAN_ISOTP_H
|
||||
#define CAN_ISOTP_H
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
// #include <linux/can.h>
|
||||
#include "can.h"
|
||||
|
||||
#define SOL_CAN_ISOTP (SOL_CAN_BASE + CAN_ISOTP)
|
||||
|
||||
/* for socket options affecting the socket (not the global system) */
|
||||
|
||||
#define CAN_ISOTP_OPTS 1 /* pass struct can_isotp_options */
|
||||
|
||||
#define CAN_ISOTP_RECV_FC 2 /* pass struct can_isotp_fc_options */
|
||||
|
||||
/* sockopts to force stmin timer values for protocol regression tests */
|
||||
|
||||
#define CAN_ISOTP_TX_STMIN 3 /* pass __u32 value in nano secs */
|
||||
/* use this time instead of value */
|
||||
/* provided in FC from the receiver */
|
||||
|
||||
#define CAN_ISOTP_RX_STMIN 4 /* pass __u32 value in nano secs */
|
||||
/* ignore received CF frames which */
|
||||
/* timestamps differ less than val */
|
||||
|
||||
#define CAN_ISOTP_LL_OPTS 5 /* pass struct can_isotp_ll_options */
|
||||
|
||||
struct can_isotp_options {
|
||||
__u32 flags; /* set flags for isotp behaviour. */
|
||||
/* __u32 value : flags see below */
|
||||
__u32 frame_txtime; /* frame transmission time (N_As/N_Ar) */
|
||||
/* __u32 value : time in nano secs */
|
||||
__u8 ext_address; /* set address for extended addressing */
|
||||
/* __u8 value : extended address */
|
||||
__u8 txpad_content; /* set content of padding byte (tx) */
|
||||
/* __u8 value : content on tx path */
|
||||
__u8 rxpad_content; /* set content of padding byte (rx) */
|
||||
/* __u8 value : content on rx path */
|
||||
__u8 rx_ext_address; /* set address for extended addressing */
|
||||
/* __u8 value : extended address (rx) */
|
||||
};
|
||||
|
||||
struct can_isotp_fc_options {
|
||||
__u8 bs; /* blocksize provided in FC frame */
|
||||
/* __u8 value : blocksize. 0 = off */
|
||||
|
||||
__u8 stmin; /* separation time provided in FC frame */
|
||||
/* __u8 value : */
|
||||
/* 0x00 - 0x7F : 0 - 127 ms */
|
||||
/* 0x80 - 0xF0 : reserved */
|
||||
/* 0xF1 - 0xF9 : 100 us - 900 us */
|
||||
/* 0xFA - 0xFF : reserved */
|
||||
|
||||
__u8 wftmax; /* max. number of wait frame transmiss. */
|
||||
/* __u8 value : 0 = omit FC N_PDU WT */
|
||||
};
|
||||
|
||||
struct can_isotp_ll_options {
|
||||
__u8 mtu; /* generated & accepted CAN frame type */
|
||||
/* __u8 value : */
|
||||
/* CAN_MTU (16) -> standard CAN 2.0 */
|
||||
/* CANFD_MTU (72) -> CAN FD frame */
|
||||
__u8 tx_dl; /* tx link layer data length in bytes */
|
||||
/* (configured maximum payload length) */
|
||||
/* __u8 value : 8,12,16,20,24,32,48,64 */
|
||||
/* => rx path supports all LL_DL values */
|
||||
__u8 tx_flags; /* set into struct canfd_frame.flags */
|
||||
/* at frame creation: e.g. CANFD_BRS */
|
||||
/* Obsolete when the BRS flag is fixed */
|
||||
/* by the CAN netdriver configuration */
|
||||
};
|
||||
|
||||
/* flags for isotp behaviour */
|
||||
|
||||
#define CAN_ISOTP_LISTEN_MODE 0x001 /* listen only (do not send FC) */
|
||||
#define CAN_ISOTP_EXTEND_ADDR 0x002 /* enable extended addressing */
|
||||
#define CAN_ISOTP_TX_PADDING 0x004 /* enable CAN frame padding tx path */
|
||||
#define CAN_ISOTP_RX_PADDING 0x008 /* enable CAN frame padding rx path */
|
||||
#define CAN_ISOTP_CHK_PAD_LEN 0x010 /* check received CAN frame padding */
|
||||
#define CAN_ISOTP_CHK_PAD_DATA 0x020 /* check received CAN frame padding */
|
||||
#define CAN_ISOTP_HALF_DUPLEX 0x040 /* half duplex error state handling */
|
||||
#define CAN_ISOTP_FORCE_TXSTMIN 0x080 /* ignore stmin from received FC */
|
||||
#define CAN_ISOTP_FORCE_RXSTMIN 0x100 /* ignore CFs depending on rx stmin */
|
||||
#define CAN_ISOTP_RX_EXT_ADDR 0x200 /* different rx extended addressing */
|
||||
#define CAN_ISOTP_WAIT_TX_DONE 0x400 /* wait for tx completion */
|
||||
#define CAN_ISOTP_SF_BROADCAST 0x800 /* 1-to-N functional addressing */
|
||||
|
||||
/* default values */
|
||||
|
||||
#define CAN_ISOTP_DEFAULT_FLAGS 0
|
||||
#define CAN_ISOTP_DEFAULT_EXT_ADDRESS 0x00
|
||||
#define CAN_ISOTP_DEFAULT_PAD_CONTENT 0xCC /* prevent bit-stuffing */
|
||||
#define CAN_ISOTP_DEFAULT_FRAME_TXTIME 0
|
||||
#define CAN_ISOTP_DEFAULT_RECV_BS 0
|
||||
#define CAN_ISOTP_DEFAULT_RECV_STMIN 0x00
|
||||
#define CAN_ISOTP_DEFAULT_RECV_WFTMAX 0
|
||||
|
||||
#define CAN_ISOTP_DEFAULT_LL_MTU CAN_MTU
|
||||
#define CAN_ISOTP_DEFAULT_LL_TX_DL CAN_MAX_DLEN
|
||||
#define CAN_ISOTP_DEFAULT_LL_TX_FLAGS 0
|
||||
|
||||
/*
|
||||
* Remark on CAN_ISOTP_DEFAULT_RECV_* values:
|
||||
*
|
||||
* We can strongly assume, that the Linux Kernel implementation of
|
||||
* CAN_ISOTP is capable to run with BS=0, STmin=0 and WFTmax=0.
|
||||
* But as we like to be able to behave as a commonly available ECU,
|
||||
* these default settings can be changed via sockopts.
|
||||
* For that reason the STmin value is intentionally _not_ checked for
|
||||
* consistency and copied directly into the flow control (FC) frame.
|
||||
*
|
||||
*/
|
||||
|
||||
#endif
|
@ -6,6 +6,10 @@
|
||||
#include <r_util.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if __linux__
|
||||
#include "i/isotp.h"
|
||||
#endif
|
||||
|
||||
#if EMSCRIPTEN || __wasi__ || defined(__serenity__)
|
||||
#define NETWORK_DISABLED 1
|
||||
#else
|
||||
@ -269,6 +273,60 @@ R_API bool r_socket_connect(RSocket *s, const char *host, const char *port, int
|
||||
if (!__connect_unix (s, host)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
} else if (proto == R_SOCKET_PROTO_CAN) {
|
||||
#if __linux__
|
||||
// host: can interface name
|
||||
// port: src and dst can identifiers
|
||||
ut32 srcid = 0;
|
||||
ut32 dstid = 0;
|
||||
sscanf (port, "0x%x/0x%x", &srcid, &dstid);
|
||||
// s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
|
||||
int fd = socket (PF_CAN, SOCK_DGRAM, CAN_ISOTP);
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
static struct can_isotp_options opts = {
|
||||
.txpad_content = 0xcc,
|
||||
.rxpad_content = 0xcc,
|
||||
.frame_txtime = 0x1000,
|
||||
};
|
||||
setsockopt (fd, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof (opts));
|
||||
static struct can_isotp_fc_options fcopts = {
|
||||
.stmin = 0xf3
|
||||
};
|
||||
setsockopt (fd, SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, &fcopts, sizeof (fcopts));
|
||||
static struct can_isotp_ll_options llopts = {
|
||||
.mtu = 8,
|
||||
.tx_dl = 8,
|
||||
};
|
||||
setsockopt (fd, SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, &llopts, sizeof (llopts));
|
||||
|
||||
struct ifreq ifr = {0};
|
||||
r_str_ncpy (ifr.ifr_name, host, sizeof (ifr.ifr_name));
|
||||
if (ioctl (fd, SIOCGIFINDEX, &ifr) == -1) {
|
||||
r_sys_perror ("ioctl");
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_can addr = {0};
|
||||
addr.can_family = AF_CAN;
|
||||
addr.can_ifindex = ifr.ifr_ifindex;
|
||||
addr.can_addr.tp.rx_id = srcid | 0x80000000;
|
||||
addr.can_addr.tp.tx_id = dstid | 0x80000000;
|
||||
|
||||
if (bind (fd, (struct sockaddr *)&addr, sizeof (addr)) < 0) {
|
||||
r_sys_perror ("bind");
|
||||
close (fd);
|
||||
return false;
|
||||
}
|
||||
s->fd = fd;
|
||||
s->is_ssl = false;
|
||||
return true;
|
||||
#else
|
||||
eprintf ("Unsupported ISOTP socket protocol\n");
|
||||
return false;
|
||||
#endif
|
||||
} else {
|
||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user