Initial import of the isotp:// plugin ##io

This commit is contained in:
pancake 2021-09-16 03:53:23 -07:00 committed by GitHub
parent c539afaa07
commit 4d2be3830f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 596 additions and 3 deletions

View File

@ -271,6 +271,7 @@ io.zip
io.r2k
io.ar
io.fd
io.isotp
io.rbuf
lang.c
lang.v

View File

@ -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
}

View File

@ -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

View File

@ -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')

View File

@ -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
View 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

View File

@ -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

View File

@ -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
View 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
View 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
View 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

View File

@ -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 */