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