#include <linux/module.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/times.h>
#include <linux/pkt_sched.h>
#include <linux/byteorder/generic.h>
#include <net/net_namespace.h>
#include <net/arp.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/route.h>
#include <net/sock.h>
#include <net/checksum.h>
#include <net/inet_common.h>
#include <linux/netfilter_ipv4.h>
#ifdef CONFIG_IP_MROUTE
#include <linux/mroute.h>
#endif
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#endif
#ifdef CONFIG_IP_MULTICAST
#define IGMP_QUERY_INTERVAL …
#define IGMP_QUERY_RESPONSE_INTERVAL …
#define IGMP_INITIAL_REPORT_DELAY …
#define IGMP_V1_SEEN(in_dev) …
#define IGMP_V2_SEEN(in_dev) …
static int unsolicited_report_interval(struct in_device *in_dev)
{ … }
static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im,
gfp_t gfp);
static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list *im);
static void igmpv3_clear_delrec(struct in_device *in_dev);
static int sf_setstate(struct ip_mc_list *pmc);
static void sf_markstate(struct ip_mc_list *pmc);
#endif
static void ip_mc_clear_src(struct ip_mc_list *pmc);
static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
int sfcount, __be32 *psfsrc, int delta);
static void ip_ma_put(struct ip_mc_list *im)
{ … }
#define for_each_pmc_rcu(in_dev, pmc) …
#define for_each_pmc_rtnl(in_dev, pmc) …
static void ip_sf_list_clear_all(struct ip_sf_list *psf)
{ … }
#ifdef CONFIG_IP_MULTICAST
static void igmp_stop_timer(struct ip_mc_list *im)
{ … }
static void igmp_start_timer(struct ip_mc_list *im, int max_delay)
{ … }
static void igmp_gq_start_timer(struct in_device *in_dev)
{ … }
static void igmp_ifc_start_timer(struct in_device *in_dev, int delay)
{ … }
static void igmp_mod_timer(struct ip_mc_list *im, int max_delay)
{ … }
#define IGMP_SIZE …
static int is_in(struct ip_mc_list *pmc, struct ip_sf_list *psf, int type,
int gdeleted, int sdeleted)
{ … }
static int
igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
{ … }
static __be32 igmpv3_get_srcaddr(struct net_device *dev,
const struct flowi4 *fl4)
{ … }
static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
{ … }
static int igmpv3_sendpack(struct sk_buff *skb)
{ … }
static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
{ … }
static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
int type, struct igmpv3_grec **ppgr, unsigned int mtu)
{ … }
#define AVAILABLE(skb) …
static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
int type, int gdeleted, int sdeleted)
{ … }
static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
{ … }
static void igmpv3_clear_zeros(struct ip_sf_list **ppsf)
{ … }
static void kfree_pmc(struct ip_mc_list *pmc)
{ … }
static void igmpv3_send_cr(struct in_device *in_dev)
{ … }
static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
int type)
{ … }
static void igmp_gq_timer_expire(struct timer_list *t)
{ … }
static void igmp_ifc_timer_expire(struct timer_list *t)
{ … }
static void igmp_ifc_event(struct in_device *in_dev)
{ … }
static void igmp_timer_expire(struct timer_list *t)
{ … }
static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
{ … }
static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
{ … }
static bool igmp_heard_report(struct in_device *in_dev, __be32 group)
{ … }
static bool igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
int len)
{ … }
int igmp_rcv(struct sk_buff *skb)
{ … }
#endif
static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr)
{ … }
static void ip_mc_filter_del(struct in_device *in_dev, __be32 addr)
{ … }
#ifdef CONFIG_IP_MULTICAST
static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im,
gfp_t gfp)
{ … }
static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list *im)
{ … }
static void igmpv3_clear_delrec(struct in_device *in_dev)
{ … }
#endif
static void __igmp_group_dropped(struct ip_mc_list *im, gfp_t gfp)
{ … }
static void igmp_group_dropped(struct ip_mc_list *im)
{ … }
static void igmp_group_added(struct ip_mc_list *im)
{ … }
static u32 ip_mc_hash(const struct ip_mc_list *im)
{ … }
static void ip_mc_hash_add(struct in_device *in_dev,
struct ip_mc_list *im)
{ … }
static void ip_mc_hash_remove(struct in_device *in_dev,
struct ip_mc_list *im)
{ … }
static void ____ip_mc_inc_group(struct in_device *in_dev, __be32 addr,
unsigned int mode, gfp_t gfp)
{ … }
void __ip_mc_inc_group(struct in_device *in_dev, __be32 addr, gfp_t gfp)
{ … }
EXPORT_SYMBOL(…);
void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
{ … }
EXPORT_SYMBOL(…);
static int ip_mc_check_iphdr(struct sk_buff *skb)
{ … }
static int ip_mc_check_igmp_reportv3(struct sk_buff *skb)
{ … }
static int ip_mc_check_igmp_query(struct sk_buff *skb)
{ … }
static int ip_mc_check_igmp_msg(struct sk_buff *skb)
{ … }
static __sum16 ip_mc_validate_checksum(struct sk_buff *skb)
{ … }
static int ip_mc_check_igmp_csum(struct sk_buff *skb)
{ … }
int ip_mc_check_igmp(struct sk_buff *skb)
{ … }
EXPORT_SYMBOL(…);
static void ip_mc_rejoin_groups(struct in_device *in_dev)
{ … }
void __ip_mc_dec_group(struct in_device *in_dev, __be32 addr, gfp_t gfp)
{ … }
EXPORT_SYMBOL(…);
void ip_mc_unmap(struct in_device *in_dev)
{ … }
void ip_mc_remap(struct in_device *in_dev)
{ … }
void ip_mc_down(struct in_device *in_dev)
{ … }
#ifdef CONFIG_IP_MULTICAST
static void ip_mc_reset(struct in_device *in_dev)
{ … }
#else
static void ip_mc_reset(struct in_device *in_dev)
{
}
#endif
void ip_mc_init_dev(struct in_device *in_dev)
{ … }
void ip_mc_up(struct in_device *in_dev)
{ … }
void ip_mc_destroy_dev(struct in_device *in_dev)
{ … }
static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr)
{ … }
static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
__be32 *psfsrc)
{ … }
#ifndef CONFIG_IP_MULTICAST
#define igmp_ifc_event …
#endif
static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
int sfcount, __be32 *psfsrc, int delta)
{ … }
static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
__be32 *psfsrc)
{ … }
#ifdef CONFIG_IP_MULTICAST
static void sf_markstate(struct ip_mc_list *pmc)
{ … }
static int sf_setstate(struct ip_mc_list *pmc)
{ … }
#endif
static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
int sfcount, __be32 *psfsrc, int delta)
{ … }
static void ip_mc_clear_src(struct ip_mc_list *pmc)
{ … }
static int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr,
unsigned int mode)
{ … }
int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr)
{ … }
EXPORT_SYMBOL(…);
int ip_mc_join_group_ssm(struct sock *sk, struct ip_mreqn *imr,
unsigned int mode)
{ … }
static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,
struct in_device *in_dev)
{ … }
int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
{ … }
EXPORT_SYMBOL(…);
int ip_mc_source(int add, int omode, struct sock *sk, struct
ip_mreq_source *mreqs, int ifindex)
{ … }
int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
{ … }
int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
sockptr_t optval, sockptr_t optlen)
{ … }
int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
sockptr_t optval, size_t ss_offset)
{ … }
int ip_mc_sf_allow(const struct sock *sk, __be32 loc_addr, __be32 rmt_addr,
int dif, int sdif)
{ … }
void ip_mc_drop_socket(struct sock *sk)
{ … }
int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u8 proto)
{ … }
#if defined(CONFIG_PROC_FS)
struct igmp_mc_iter_state { … };
#define igmp_mc_seq_private(seq) …
static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq)
{ … }
static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_list *im)
{ … }
static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos)
{ … }
static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(rcu)
{ … }
static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ … }
static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
__releases(rcu)
{ … }
static int igmp_mc_seq_show(struct seq_file *seq, void *v)
{ … }
static const struct seq_operations igmp_mc_seq_ops = …;
struct igmp_mcf_iter_state { … };
#define igmp_mcf_seq_private(seq) …
static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
{ … }
static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_list *psf)
{ … }
static struct ip_sf_list *igmp_mcf_get_idx(struct seq_file *seq, loff_t pos)
{ … }
static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(rcu)
{ … }
static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ … }
static void igmp_mcf_seq_stop(struct seq_file *seq, void *v)
__releases(rcu)
{ … }
static int igmp_mcf_seq_show(struct seq_file *seq, void *v)
{ … }
static const struct seq_operations igmp_mcf_seq_ops = …;
static int __net_init igmp_net_init(struct net *net)
{ … }
static void __net_exit igmp_net_exit(struct net *net)
{ … }
static struct pernet_operations igmp_net_ops = …;
#endif
static int igmp_netdev_event(struct notifier_block *this,
unsigned long event, void *ptr)
{ … }
static struct notifier_block igmp_notifier = …;
int __init igmp_mc_init(void)
{ … }