Beispiel #1
0
int igmp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
	__u32 daddr, unsigned short len, __u32 saddr, int redo,
	struct inet_protocol *protocol)
{
	/* This basically follows the spec line by line -- see RFC1112 */
	struct igmphdr *ih;

	/*
	 *	Mrouted needs to able to query local interfaces. So
	 *	report for the device this was sent at. (Which can
	 *	be the loopback this time)
	 */

	if(dev->flags&IFF_LOOPBACK)
	{
		dev=ip_dev_find(saddr);
		if(dev==NULL)
			dev=&loopback_dev;
	}
	ih=(struct igmphdr *)skb->h.raw;

	if(len <sizeof(struct igmphdr) || skb->ip_hdr->ttl<1 || ip_compute_csum((void *)skb->h.raw,sizeof(struct igmphdr)))
	{
		kfree_skb(skb, FREE_READ);
		return 0;
	}
	
	/*
	 *	I have a report that someone does this!
	 */
	 
	if(saddr==0)
	{
		printk(KERN_INFO "Broken multicast host using 0.0.0.0 heard on %s\n",
			dev->name);
		kfree_skb(skb, FREE_READ);
		return 0;
	}

	if(ih->type==IGMP_HOST_MEMBERSHIP_QUERY && daddr==IGMP_ALL_HOSTS)
		igmp_heard_query(dev,ih->code);
	if(ih->type==IGMP_HOST_MEMBERSHIP_REPORT && daddr==ih->group)
		igmp_heard_report(dev,ih->group, saddr);
	if(ih->type==IGMP_HOST_NEW_MEMBERSHIP_REPORT && daddr==ih->group)
		igmp_heard_report(dev,ih->group, saddr);
	kfree_skb(skb, FREE_READ);
	return 0;
}
Beispiel #2
0
int igmp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
	unsigned long daddr, unsigned short len, unsigned long saddr, int redo,
	struct inet_protocol *protocol)
{
	/* This basically follows the spec line by line -- see RFC1112 */
	struct igmphdr *igh=(struct igmphdr *)skb->h.raw;
	
	if(skb->ip_hdr->ttl!=1 || ip_compute_csum((void *)igh,sizeof(*igh)))
	{
		kfree_skb(skb, FREE_READ);
		return 0;
	}
	
	if(igh->type==IGMP_HOST_MEMBERSHIP_QUERY && daddr==IGMP_ALL_HOSTS)
		igmp_heard_query(dev);
	if(igh->type==IGMP_HOST_MEMBERSHIP_REPORT && daddr==igh->group)
		igmp_heard_report(dev,igh->group);
	kfree_skb(skb, FREE_READ);
	return 0;
}
Beispiel #3
0
int igmp_rcv(struct sk_buff *skb, unsigned short len)
{
	/* This basically follows the spec line by line -- see RFC1112 */
	struct igmphdr *ih = skb->h.igmph;
	struct in_device *in_dev = skb->dev->ip_ptr;

	if (len < sizeof(struct igmphdr) || ip_compute_csum((void *)ih, len)
	    || in_dev==NULL) {
		kfree_skb(skb);
		return 0;
	}
	
	switch (ih->type) {
	case IGMP_HOST_MEMBERSHIP_QUERY:
		igmp_heard_query(in_dev, ih->code, ih->group);
		break;
	case IGMP_HOST_MEMBERSHIP_REPORT:
	case IGMP_HOST_NEW_MEMBERSHIP_REPORT:
		/* Is it our report looped back? */
		if (((struct rtable*)skb->dst)->key.iif == 0)
			break;
		igmp_heard_report(in_dev, ih->group);
		break;
	case IGMP_PIM:
#ifdef CONFIG_IP_PIMSM_V1
		return pim_rcv_v1(skb, len);
#endif
	case IGMP_DVMRP:
	case IGMP_TRACE:
	case IGMP_HOST_LEAVE_MESSAGE:
	case IGMP_MTRACE:
	case IGMP_MTRACE_RESP:
		break;
	default:
		NETDEBUG(printk(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type));
	}
	kfree_skb(skb);
	return 0;
}
int igmp_rcv(struct sk_buff *skb)
{
    /* This basically follows the spec line by line -- see RFC1112 */
    struct igmphdr *ih = skb->h.igmph;
    struct in_device *in_dev = in_dev_get(skb->dev);
    int len = skb->len;

    if (in_dev==NULL) {
        kfree_skb(skb);
        return 0;
    }

    if (skb_is_nonlinear(skb)) {
        if (skb_linearize(skb, GFP_ATOMIC) != 0) {
            kfree_skb(skb);
            return -ENOMEM;
        }
        ih = skb->h.igmph;
    }

    if (len < sizeof(struct igmphdr) || ip_compute_csum((void *)ih, len)) {
        in_dev_put(in_dev);
        kfree_skb(skb);
        return 0;
    }

#ifdef CONFIG_RG_IGMP_PROXY
    igmprx_recv(skb);
#endif
#ifdef CONFIG_RG_IGMP_PROXY_MODULE
    if (igmp_proxy_recv)
        igmp_proxy_recv(skb);
#endif

    switch (ih->type) {
    case IGMP_HOST_MEMBERSHIP_QUERY:
        igmp_heard_query(in_dev, ih->code, ih->group);
        break;
    case IGMP_HOST_MEMBERSHIP_REPORT:
    case IGMP_HOST_NEW_MEMBERSHIP_REPORT:
        /* Is it our report looped back? */
        if (((struct rtable*)skb->dst)->key.iif == 0)
            break;
        igmp_heard_report(in_dev, ih->group);
        break;
    case IGMP_PIM:
#ifdef CONFIG_IP_PIMSM_V1
        in_dev_put(in_dev);
        return pim_rcv_v1(skb);
#endif
    case IGMP_DVMRP:
    case IGMP_TRACE:
    case IGMP_HOST_LEAVE_MESSAGE:
    case IGMP_MTRACE:
    case IGMP_MTRACE_RESP:
        break;
    default:
        // NETDEBUG(printk(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type));
        ;
    }
    in_dev_put(in_dev);
    kfree_skb(skb);
    return 0;
}