// SPDX-License-Identifier: GPL-2.0-or-later
/*
* dvb_net.c
*
* Copyright (C) 2001 Convergence integrated media GmbH
* Ralph Metzler <ralph@convergence.de>
* Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
*
* ULE Decapsulation code:
* Copyright (C) 2003, 2004 gcs - Global Communication & Services GmbH.
* and Department of Scientific Computing
* Paris Lodron University of Salzburg.
* Hilmar Linder <hlinder@cosy.sbg.ac.at>
* and Wolfram Stering <wstering@cosy.sbg.ac.at>
*
* ULE Decaps according to RFC 4326.
*/
/*
* ULE ChangeLog:
* Feb 2004: hl/ws v1: Implementing draft-fair-ipdvb-ule-01.txt
*
* Dec 2004: hl/ws v2: Implementing draft-ietf-ipdvb-ule-03.txt:
* ULE Extension header handling.
* Bugreports by Moritz Vieth and Hanno Tersteegen,
* Fraunhofer Institute for Open Communication Systems
* Competence Center for Advanced Satellite Communications.
* Bugfixes and robustness improvements.
* Filtering on dest MAC addresses, if present (D-Bit = 0)
* DVB_ULE_DEBUG compile-time option.
* Apr 2006: cp v3: Bugfixes and compliency with RFC 4326 (ULE) by
* Christian Praehauser <cpraehaus@cosy.sbg.ac.at>,
* Paris Lodron University of Salzburg.
*/
/*
* FIXME / TODO (dvb_net.c):
*
* Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero.
*
*/
#define pr_fmt(fmt) "dvb_net: " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/dvb/net.h>
#include <linux/uio.h>
#include <linux/uaccess.h>
#include <linux/crc32.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <media/dvb_demux.h>
#include <media/dvb_net.h>
static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
{
unsigned int j;
for (j = 0; j < cnt; j++)
c = crc32_be( c, iov[j].iov_base, iov[j].iov_len );
return c;
}
#define DVB_NET_MULTICAST_MAX 10
#ifdef DVB_ULE_DEBUG
/*
* The code inside DVB_ULE_DEBUG keeps a history of the
* last 100 TS cells processed.
*/
static unsigned char ule_hist[100*TS_SZ] = { 0 };
static unsigned char *ule_where = ule_hist, ule_dump;
static void hexdump(const unsigned char *buf, unsigned short len)
{
print_hex_dump_debug("", DUMP_PREFIX_OFFSET, 16, 1, buf, len, true);
}
#endif
struct dvb_net_priv {
int in_use;
u16 pid;
struct net_device *net;
struct dvb_net *host;
struct dmx_demux *demux;
struct dmx_section_feed *secfeed;
struct dmx_section_filter *secfilter;
struct dmx_ts_feed *tsfeed;
int multi_num;
struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX];
unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6];
int rx_mode;
#define RX_MODE_UNI 0
#define RX_MODE_MULTI 1
#define RX_MODE_ALL_MULTI 2
#define RX_MODE_PROMISC 3
struct work_struct set_multicast_list_wq;
struct work_struct restart_net_feed_wq;
unsigned char feedtype; /* Either FEED_TYPE_ or FEED_TYPE_ULE */
int need_pusi; /* Set to 1, if synchronization on PUSI required. */
unsigned char tscc; /* TS continuity counter after sync on PUSI. */
struct sk_buff *ule_skb; /* ULE SNDU decodes into this buffer. */
unsigned char *ule_next_hdr; /* Pointer into skb to next ULE extension header. */
unsigned short ule_sndu_len; /* ULE SNDU length in bytes, w/o D-Bit. */
unsigned short ule_sndu_type; /* ULE SNDU type field, complete. */
unsigned char ule_sndu_type_1; /* ULE SNDU type field, if split across 2 TS cells. */
unsigned char ule_dbit; /* Whether the DestMAC address present
* or not (bit is set). */
unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */
int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */
unsigned long ts_count; /* Curren
|