iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
}
+ err = -EPERM;
+ if (!vx_check(0, VX_ADMIN) && !capable(CAP_NET_RAW)
+ && (!raw_addr_in_list(0, 0, iph->saddr, sk->sk_nx_info)))
+ goto error;
err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
dst_output);
err = -EFAULT;
kfree_skb(skb);
error:
- IP_INC_STATS(IpOutDiscards);
+ IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
return err;
}
.proto = inet->hdrincl ? IPPROTO_RAW :
sk->sk_protocol,
};
+
+ if (sk->sk_nx_info) {
+ err = ip_find_src(sk->sk_nx_info, &rt, &fl);
+
+ if (err)
+ goto done;
+ }
err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
}
if (err)
*/
ip_ra_control(sk, 0, NULL);
- inet_sock_release(sk);
+ sk_common_release(sk);
}
/* This gets rid of all the nasties in af_inet. -DaveM */
}
if (inet->cmsg_flags)
ip_cmsg_recv(msg, skb);
+ if (flags & MSG_TRUNC)
+ copied = skb->len;
done:
skb_free_datagram(sk, skb);
-out: return err ? : copied;
+out: return err ? err : copied;
}
static int raw_init(struct sock *sk)
return 0;
}
-static int raw_seticmpfilter(struct sock *sk, char *optval, int optlen)
+static int raw_seticmpfilter(struct sock *sk, char __user *optval, int optlen)
{
if (optlen > sizeof(struct icmp_filter))
optlen = sizeof(struct icmp_filter);
return 0;
}
-static int raw_geticmpfilter(struct sock *sk, char *optval, int *optlen)
+static int raw_geticmpfilter(struct sock *sk, char __user *optval, int __user *optlen)
{
int len, ret = -EFAULT;
}
static int raw_setsockopt(struct sock *sk, int level, int optname,
- char *optval, int optlen)
+ char __user *optval, int optlen)
{
if (level != SOL_RAW)
return ip_setsockopt(sk, level, optname, optval, optlen);
}
static int raw_getsockopt(struct sock *sk, int level, int optname,
- char *optval, int *optlen)
+ char __user *optval, int __user *optlen)
{
if (level != SOL_RAW)
return ip_getsockopt(sk, level, optname, optval, optlen);
switch (cmd) {
case SIOCOUTQ: {
int amount = atomic_read(&sk->sk_wmem_alloc);
- return put_user(amount, (int *)arg);
+ return put_user(amount, (int __user *)arg);
}
case SIOCINQ: {
struct sk_buff *skb;
if (skb != NULL)
amount = skb->len;
spin_unlock_irq(&sk->sk_receive_queue.lock);
- return put_user(amount, (int *)arg);
+ return put_user(amount, (int __user *)arg);
}
default:
#ifdef CONFIG_IP_MROUTE
- return ipmr_ioctl(sk, cmd, arg);
+ return ipmr_ioctl(sk, cmd, (void __user *)arg);
#else
return -ENOIOCTLCMD;
#endif
struct proto raw_prot = {
.name = "RAW",
.close = raw_close,
- .connect = udp_connect,
+ .connect = ip4_datagram_connect,
.disconnect = udp_disconnect,
.ioctl = raw_ioctl,
.init = raw_init,