linux/net/can/isotp.c

// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/* isotp.c - ISO 15765-2 CAN transport protocol for protocol family CAN
 *
 * This implementation does not provide ISO-TP specific return values to the
 * userspace.
 *
 * - RX path timeout of data reception leads to -ETIMEDOUT
 * - RX path SN mismatch leads to -EILSEQ
 * - RX path data reception with wrong padding leads to -EBADMSG
 * - TX path flowcontrol reception timeout leads to -ECOMM
 * - TX path flowcontrol reception overflow leads to -EMSGSIZE
 * - TX path flowcontrol reception with wrong layout/padding leads to -EBADMSG
 * - when a transfer (tx) is on the run the next write() blocks until it's done
 * - use CAN_ISOTP_WAIT_TX_DONE flag to block the caller until the PDU is sent
 * - as we have static buffers the check whether the PDU fits into the buffer
 *   is done at FF reception time (no support for sending 'wait frames')
 *
 * Copyright (c) 2020 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.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/hrtimer.h>
#include <linux/wait.h>
#include <linux/uio.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/socket.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/can.h>
#include <linux/can/core.h>
#include <linux/can/skb.h>
#include <linux/can/isotp.h>
#include <linux/slab.h>
#include <net/sock.h>
#include <net/net_namespace.h>

MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_ALIAS();

#define ISOTP_MIN_NAMELEN

#define SINGLE_MASK(id)

/* Since ISO 15765-2:2016 the CAN isotp protocol supports more than 4095
 * byte per ISO PDU as the FF_DL can take full 32 bit values (4 Gbyte).
 * We would need some good concept to handle this between user space and
 * kernel space. For now set the static buffer to something about 8 kbyte
 * to be able to test this new functionality.
 */
#define DEFAULT_MAX_PDU_SIZE

/* maximum PDU size before ISO 15765-2:2016 extension was 4095 */
#define MAX_12BIT_PDU_SIZE

/* limit the isotp pdu size from the optional module parameter to 1MByte */
#define MAX_PDU_SIZE

static unsigned int max_pdu_size __read_mostly =;
module_param(max_pdu_size, uint, 0444);
MODULE_PARM_DESC();

/* N_PCI type values in bits 7-4 of N_PCI bytes */
#define N_PCI_SF
#define N_PCI_FF
#define N_PCI_CF
#define N_PCI_FC

#define N_PCI_SZ
#define SF_PCI_SZ4
#define SF_PCI_SZ8
#define FF_PCI_SZ12
#define FF_PCI_SZ32
#define FC_CONTENT_SZ

#define ISOTP_CHECK_PADDING
#define ISOTP_ALL_BC_FLAGS

/* Flow Status given in FC frame */
#define ISOTP_FC_CTS
#define ISOTP_FC_WT
#define ISOTP_FC_OVFLW

#define ISOTP_FC_TIMEOUT
#define ISOTP_ECHO_TIMEOUT

enum {};

struct tpcon {};

struct isotp_sock {};

static LIST_HEAD(isotp_notifier_list);
static DEFINE_SPINLOCK(isotp_notifier_lock);
static struct isotp_sock *isotp_busy_notifier;

static inline struct isotp_sock *isotp_sk(const struct sock *sk)
{}

static u32 isotp_bc_flags(struct isotp_sock *so)
{}

static bool isotp_register_rxid(struct isotp_sock *so)
{}

static enum hrtimer_restart isotp_rx_timer_handler(struct hrtimer *hrtimer)
{}

static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus)
{}

static void isotp_rcv_skb(struct sk_buff *skb, struct sock *sk)
{}

static u8 padlen(u8 datalen)
{}

/* check for length optimization and return 1/true when the check fails */
static int check_optimized(struct canfd_frame *cf, int start_index)
{}

/* check padding and return 1/true when the check fails */
static int check_pad(struct isotp_sock *so, struct canfd_frame *cf,
		     int start_index, u8 content)
{}

static void isotp_send_cframe(struct isotp_sock *so);

static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
{}

static int isotp_rcv_sf(struct sock *sk, struct canfd_frame *cf, int pcilen,
			struct sk_buff *skb, int len)
{}

static int isotp_rcv_ff(struct sock *sk, struct canfd_frame *cf, int ae)
{}

static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae,
			struct sk_buff *skb)
{}

static void isotp_rcv(struct sk_buff *skb, void *data)
{}

static void isotp_fill_dataframe(struct canfd_frame *cf, struct isotp_sock *so,
				 int ae, int off)
{}

static void isotp_send_cframe(struct isotp_sock *so)
{}

static void isotp_create_fframe(struct canfd_frame *cf, struct isotp_sock *so,
				int ae)
{}

static void isotp_rcv_echo(struct sk_buff *skb, void *data)
{}

static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
{}

static enum hrtimer_restart isotp_txfr_timer_handler(struct hrtimer *hrtimer)
{}

static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
{}

static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
			 int flags)
{}

static int isotp_release(struct socket *sock)
{}

static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
{}

static int isotp_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
{}

static int isotp_setsockopt_locked(struct socket *sock, int level, int optname,
			    sockptr_t optval, unsigned int optlen)
{}

static int isotp_setsockopt(struct socket *sock, int level, int optname,
			    sockptr_t optval, unsigned int optlen)

{}

static int isotp_getsockopt(struct socket *sock, int level, int optname,
			    char __user *optval, int __user *optlen)
{}

static void isotp_notify(struct isotp_sock *so, unsigned long msg,
			 struct net_device *dev)
{}

static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
			  void *ptr)
{}

static int isotp_init(struct sock *sk)
{}

static __poll_t isotp_poll(struct file *file, struct socket *sock, poll_table *wait)
{}

static int isotp_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd,
				  unsigned long arg)
{}

static const struct proto_ops isotp_ops =;

static struct proto isotp_proto __read_mostly =;

static const struct can_proto isotp_can_proto =;

static struct notifier_block canisotp_notifier =;

static __init int isotp_module_init(void)
{}

static __exit void isotp_module_exit(void)
{}

module_init();
module_exit(isotp_module_exit);