patch-2.4.4 linux/net/ipv4/ipmr.c
Next file: linux/net/ipv4/netfilter/Makefile
Previous file: linux/net/ipv4/ipip.c
Back to the patch index
Back to the overall index
- Lines: 100
- Date:
Thu Apr 12 12:11:39 2001
- Orig file:
v2.4.3/linux/net/ipv4/ipmr.c
- Orig date:
Tue Nov 28 21:53:45 2000
diff -u --recursive --new-file v2.4.3/linux/net/ipv4/ipmr.c linux/net/ipv4/ipmr.c
@@ -9,7 +9,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Version: $Id: ipmr.c,v 1.55 2000/11/28 13:13:27 davem Exp $
+ * Version: $Id: ipmr.c,v 1.59 2001/02/23 06:32:11 davem Exp $
*
* Fixes:
* Michael Chastain : Incorrect size of copying.
@@ -980,6 +980,9 @@
return -EFAULT;
olr=min(olr,sizeof(int));
+ if(olr<0)
+ return -EINVAL;
+
if(put_user(olr,optlen))
return -EFAULT;
if(optname==MRT_VERSION)
@@ -1092,7 +1095,7 @@
iph->protocol = IPPROTO_IPIP;
iph->ihl = 5;
iph->tot_len = htons(skb->len);
- ip_select_ident(iph, skb->dst);
+ ip_select_ident(iph, skb->dst, NULL);
ip_send_check(iph);
skb->h.ipiph = skb->nh.iph;
@@ -1383,14 +1386,22 @@
* Handle IGMP messages of PIMv1
*/
-int pim_rcv_v1(struct sk_buff * skb, unsigned short len)
+int pim_rcv_v1(struct sk_buff * skb)
{
struct igmphdr *pim = (struct igmphdr*)skb->h.raw;
struct iphdr *encap;
struct net_device *reg_dev = NULL;
+ if (skb_is_nonlinear(skb)) {
+ if (skb_linearize(skb, GFP_ATOMIC) != 0) {
+ kfree_skb(skb);
+ return -ENOMEM;
+ }
+ pim = (struct igmphdr*)skb->h.raw;
+ }
+
if (!mroute_do_pim ||
- len < sizeof(*pim) + sizeof(*encap) ||
+ skb->len < sizeof(*pim) + sizeof(*encap) ||
pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) {
kfree_skb(skb);
return -EINVAL;
@@ -1405,7 +1416,7 @@
*/
if (!MULTICAST(encap->daddr) ||
ntohs(encap->tot_len) == 0 ||
- ntohs(encap->tot_len) + sizeof(*pim) > len) {
+ ntohs(encap->tot_len) + sizeof(*pim) > skb->len) {
kfree_skb(skb);
return -EINVAL;
}
@@ -1445,17 +1456,25 @@
#endif
#ifdef CONFIG_IP_PIMSM_V2
-int pim_rcv(struct sk_buff * skb, unsigned short len)
+int pim_rcv(struct sk_buff * skb)
{
struct pimreghdr *pim = (struct pimreghdr*)skb->h.raw;
struct iphdr *encap;
struct net_device *reg_dev = NULL;
- if (len < sizeof(*pim) + sizeof(*encap) ||
+ if (skb_is_nonlinear(skb)) {
+ if (skb_linearize(skb, GFP_ATOMIC) != 0) {
+ kfree_skb(skb);
+ return -ENOMEM;
+ }
+ pim = (struct pimreghdr*)skb->h.raw;
+ }
+
+ if (skb->len < sizeof(*pim) + sizeof(*encap) ||
pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) ||
(pim->flags&PIM_NULL_REGISTER) ||
(ip_compute_csum((void *)pim, sizeof(*pim)) != 0 &&
- ip_compute_csum((void *)pim, len))) {
+ ip_compute_csum((void *)pim, skb->len))) {
kfree_skb(skb);
return -EINVAL;
}
@@ -1464,7 +1483,7 @@
encap = (struct iphdr*)(skb->h.raw + sizeof(struct pimreghdr));
if (!MULTICAST(encap->daddr) ||
ntohs(encap->tot_len) == 0 ||
- ntohs(encap->tot_len) + sizeof(*pim) > len) {
+ ntohs(encap->tot_len) + sizeof(*pim) > skb->len) {
kfree_skb(skb);
return -EINVAL;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)