git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
netfilter: xtables: add struct xt_mtchk_param::net
[safe/jmp/linux-2.6]
/
net
/
ipv4
/
ip_sockglue.c
diff --git
a/net/ipv4/ip_sockglue.c
b/net/ipv4/ip_sockglue.c
index
624b534
..
cafad9b
100644
(file)
--- a/
net/ipv4/ip_sockglue.c
+++ b/
net/ipv4/ip_sockglue.c
@@
-57,7
+57,7
@@
static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
{
struct in_pktinfo info;
static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
{
struct in_pktinfo info;
- struct rtable *rt = skb
->rtable
;
+ struct rtable *rt = skb
_rtable(skb)
;
info.ipi_addr.s_addr = ip_hdr(skb)->daddr;
if (rt) {
info.ipi_addr.s_addr = ip_hdr(skb)->daddr;
if (rt) {
@@
-127,11
+127,11
@@
static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
security_release_secctx(secdata, seclen);
}
security_release_secctx(secdata, seclen);
}
-void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
+
static
void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
{
struct sockaddr_in sin;
struct iphdr *iph = ip_hdr(skb);
{
struct sockaddr_in sin;
struct iphdr *iph = ip_hdr(skb);
-
u16 *ports = (u16 *)
skb_transport_header(skb);
+
__be16 *ports = (__be16 *)
skb_transport_header(skb);
if (skb_transport_offset(skb) + 4 > skb->len)
return;
if (skb_transport_offset(skb) + 4 > skb->len)
return;
@@
-157,38
+157,39
@@
void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
/* Ordered by supposed usage frequency */
if (flags & 1)
ip_cmsg_recv_pktinfo(msg, skb);
/* Ordered by supposed usage frequency */
if (flags & 1)
ip_cmsg_recv_pktinfo(msg, skb);
- if ((flags
>>=
1) == 0)
+ if ((flags
>>=
1) == 0)
return;
if (flags & 1)
ip_cmsg_recv_ttl(msg, skb);
return;
if (flags & 1)
ip_cmsg_recv_ttl(msg, skb);
- if ((flags
>>=
1) == 0)
+ if ((flags
>>=
1) == 0)
return;
if (flags & 1)
ip_cmsg_recv_tos(msg, skb);
return;
if (flags & 1)
ip_cmsg_recv_tos(msg, skb);
- if ((flags
>>=
1) == 0)
+ if ((flags
>>=
1) == 0)
return;
if (flags & 1)
ip_cmsg_recv_opts(msg, skb);
return;
if (flags & 1)
ip_cmsg_recv_opts(msg, skb);
- if ((flags
>>=
1) == 0)
+ if ((flags
>>=
1) == 0)
return;
if (flags & 1)
ip_cmsg_recv_retopts(msg, skb);
return;
if (flags & 1)
ip_cmsg_recv_retopts(msg, skb);
- if ((flags
>>=
1) == 0)
+ if ((flags
>>=
1) == 0)
return;
if (flags & 1)
ip_cmsg_recv_security(msg, skb);
return;
if (flags & 1)
ip_cmsg_recv_security(msg, skb);
- if ((flags
>>=
1) == 0)
+ if ((flags
>>=
1) == 0)
return;
if (flags & 1)
ip_cmsg_recv_dstaddr(msg, skb);
}
return;
if (flags & 1)
ip_cmsg_recv_dstaddr(msg, skb);
}
+EXPORT_SYMBOL(ip_cmsg_recv);
int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
{
int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
{
@@
-203,7
+204,8
@@
int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
switch (cmsg->cmsg_type) {
case IP_RETOPTS:
err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
switch (cmsg->cmsg_type) {
case IP_RETOPTS:
err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
- err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40);
+ err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
+ err < 40 ? err : 40);
if (err)
return err;
break;
if (err)
return err;
break;
@@
-238,17
+240,18
@@
int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
struct ip_ra_chain *ip_ra_chain;
DEFINE_RWLOCK(ip_ra_lock);
struct ip_ra_chain *ip_ra_chain;
DEFINE_RWLOCK(ip_ra_lock);
-int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *))
+int ip_ra_control(struct sock *sk, unsigned char on,
+ void (*destructor)(struct sock *))
{
struct ip_ra_chain *ra, *new_ra, **rap;
{
struct ip_ra_chain *ra, *new_ra, **rap;
- if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num == IPPROTO_RAW)
+ if (sk->sk_type != SOCK_RAW || inet_sk(sk)->
inet_
num == IPPROTO_RAW)
return -EINVAL;
new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
write_lock_bh(&ip_ra_lock);
return -EINVAL;
new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
write_lock_bh(&ip_ra_lock);
- for (rap = &ip_ra_chain; (ra
=
*rap) != NULL; rap = &ra->next) {
+ for (rap = &ip_ra_chain; (ra
=
*rap) != NULL; rap = &ra->next) {
if (ra->sk == sk) {
if (on) {
write_unlock_bh(&ip_ra_lock);
if (ra->sk == sk) {
if (on) {
write_unlock_bh(&ip_ra_lock);
@@
-416,7
+419,8
@@
int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
/* Reset and regenerate socket error */
spin_lock_bh(&sk->sk_error_queue.lock);
sk->sk_err = 0;
/* Reset and regenerate socket error */
spin_lock_bh(&sk->sk_error_queue.lock);
sk->sk_err = 0;
- if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {
+ skb2 = skb_peek(&sk->sk_error_queue);
+ if (skb2 != NULL) {
sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
spin_unlock_bh(&sk->sk_error_queue.lock);
sk->sk_error_report(sk);
sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
spin_unlock_bh(&sk->sk_error_queue.lock);
sk->sk_error_report(sk);
@@
-431,12
+435,12
@@
out:
/*
/*
- * Socket option code for IP. This is the end of the line after any
TCP,UDP etc options on
- * an IP socket.
+ * Socket option code for IP. This is the end of the line after any
+ *
TCP,UDP etc options on
an IP socket.
*/
static int do_ip_setsockopt(struct sock *sk, int level,
*/
static int do_ip_setsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int optlen)
+ int optname, char __user *optval,
unsigned
int optlen)
{
struct inet_sock *inet = inet_sk(sk);
int val = 0, err;
{
struct inet_sock *inet = inet_sk(sk);
int val = 0, err;
@@
-449,6
+453,7
@@
static int do_ip_setsockopt(struct sock *sk, int level,
(1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
(1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
optname == IP_MULTICAST_TTL ||
(1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
(1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
optname == IP_MULTICAST_TTL ||
+ optname == IP_MULTICAST_ALL ||
optname == IP_MULTICAST_LOOP ||
optname == IP_RECVORIGDSTADDR) {
if (optlen >= sizeof(int)) {
optname == IP_MULTICAST_LOOP ||
optname == IP_RECVORIGDSTADDR) {
if (optlen >= sizeof(int)) {
@@
-474,8
+479,8
@@
static int do_ip_setsockopt(struct sock *sk, int level,
switch (optname) {
case IP_OPTIONS:
{
switch (optname) {
case IP_OPTIONS:
{
- struct ip_options *
opt = NULL;
- if (optlen > 40
|| optlen < 0
)
+ struct ip_options *opt = NULL;
+ if (optlen > 40)
goto e_inval;
err = ip_options_get_from_user(sock_net(sk), &opt,
optval, optlen);
goto e_inval;
err = ip_options_get_from_user(sock_net(sk), &opt,
optval, optlen);
@@
-487,7
+492,7
@@
static int do_ip_setsockopt(struct sock *sk, int level,
if (sk->sk_family == PF_INET ||
(!((1 << sk->sk_state) &
(TCPF_LISTEN | TCPF_CLOSE)) &&
if (sk->sk_family == PF_INET ||
(!((1 << sk->sk_state) &
(TCPF_LISTEN | TCPF_CLOSE)) &&
- inet->daddr != LOOPBACK4_IPV6)) {
+ inet->
inet_
daddr != LOOPBACK4_IPV6)) {
#endif
if (inet->opt)
icsk->icsk_ext_hdr_len -= inet->opt->optlen;
#endif
if (inet->opt)
icsk->icsk_ext_hdr_len -= inet->opt->optlen;
@@
-556,9
+561,9
@@
static int do_ip_setsockopt(struct sock *sk, int level,
}
break;
case IP_TTL:
}
break;
case IP_TTL:
- if (optlen
<
1)
+ if (optlen
<
1)
goto e_inval;
goto e_inval;
- if (val != -1 && (val <
1 || val>
255))
+ if (val != -1 && (val <
0 || val >
255))
goto e_inval;
inet->uc_ttl = val;
break;
goto e_inval;
inet->uc_ttl = val;
break;
@@
-570,7
+575,7
@@
static int do_ip_setsockopt(struct sock *sk, int level,
inet->hdrincl = val ? 1 : 0;
break;
case IP_MTU_DISCOVER:
inet->hdrincl = val ? 1 : 0;
break;
case IP_MTU_DISCOVER:
- if (val
<0 || val>3
)
+ if (val
< IP_PMTUDISC_DONT || val > IP_PMTUDISC_PROBE
)
goto e_inval;
inet->pmtudisc = val;
break;
goto e_inval;
inet->pmtudisc = val;
break;
@@
-582,7
+587,7
@@
static int do_ip_setsockopt(struct sock *sk, int level,
case IP_MULTICAST_TTL:
if (sk->sk_type == SOCK_STREAM)
goto e_inval;
case IP_MULTICAST_TTL:
if (sk->sk_type == SOCK_STREAM)
goto e_inval;
- if (optlen
<
1)
+ if (optlen
<
1)
goto e_inval;
if (val == -1)
val = 1;
goto e_inval;
if (val == -1)
val = 1;
@@
-591,7
+596,7
@@
static int do_ip_setsockopt(struct sock *sk, int level,
inet->mc_ttl = val;
break;
case IP_MULTICAST_LOOP:
inet->mc_ttl = val;
break;
case IP_MULTICAST_LOOP:
- if (optlen
<
1)
+ if (optlen
<
1)
goto e_inval;
inet->mc_loop = !!val;
break;
goto e_inval;
inet->mc_loop = !!val;
break;
@@
-606,6
+611,9
@@
static int do_ip_setsockopt(struct sock *sk, int level,
* Check the arguments are allowable
*/
* Check the arguments are allowable
*/
+ if (optlen < sizeof(struct in_addr))
+ goto e_inval;
+
err = -EFAULT;
if (optlen >= sizeof(struct ip_mreqn)) {
if (copy_from_user(&mreq, optval, sizeof(mreq)))
err = -EFAULT;
if (optlen >= sizeof(struct ip_mreqn)) {
if (copy_from_user(&mreq, optval, sizeof(mreq)))
@@
-613,7
+621,8
@@
static int do_ip_setsockopt(struct sock *sk, int level,
} else {
memset(&mreq, 0, sizeof(mreq));
if (optlen >= sizeof(struct in_addr) &&
} else {
memset(&mreq, 0, sizeof(mreq));
if (optlen >= sizeof(struct in_addr) &&
- copy_from_user(&mreq.imr_address, optval, sizeof(struct in_addr)))
+ copy_from_user(&mreq.imr_address, optval,
+ sizeof(struct in_addr)))
break;
}
break;
}
@@
-625,17
+634,16
@@
static int do_ip_setsockopt(struct sock *sk, int level,
break;
}
dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
break;
}
dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
- if (dev)
{
+ if (dev)
mreq.imr_ifindex = dev->ifindex;
mreq.imr_ifindex = dev->ifindex;
- dev_put(dev);
- }
} else
} else
- dev =
__
dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
+ dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
err = -EADDRNOTAVAIL;
if (!dev)
break;
err = -EADDRNOTAVAIL;
if (!dev)
break;
+ dev_put(dev);
err = -EINVAL;
if (sk->sk_bound_dev_if &&
err = -EINVAL;
if (sk->sk_bound_dev_if &&
@@
-677,7
+685,6
@@
static int do_ip_setsockopt(struct sock *sk, int level,
}
case IP_MSFILTER:
{
}
case IP_MSFILTER:
{
- extern int sysctl_igmp_max_msf;
struct ip_msfilter *msf;
if (optlen < IP_MSFILTER_SIZE(0))
struct ip_msfilter *msf;
if (optlen < IP_MSFILTER_SIZE(0))
@@
-831,7
+838,6
@@
static int do_ip_setsockopt(struct sock *sk, int level,
}
case MCAST_MSFILTER:
{
}
case MCAST_MSFILTER:
{
- extern int sysctl_igmp_max_msf;
struct sockaddr_in *psin;
struct ip_msfilter *msf = NULL;
struct group_filter *gsf = NULL;
struct sockaddr_in *psin;
struct ip_msfilter *msf = NULL;
struct group_filter *gsf = NULL;
@@
-849,9
+855,9
@@
static int do_ip_setsockopt(struct sock *sk, int level,
break;
}
err = -EFAULT;
break;
}
err = -EFAULT;
- if (copy_from_user(gsf, optval, optlen))
{
+ if (copy_from_user(gsf, optval, optlen))
goto mc_msf_out;
goto mc_msf_out;
- }
+
/* numsrc >= (4G-140)/128 overflow in 32 bits */
if (gsf->gf_numsrc >= 0x1ffffff ||
gsf->gf_numsrc > sysctl_igmp_max_msf) {
/* numsrc >= (4G-140)/128 overflow in 32 bits */
if (gsf->gf_numsrc >= 0x1ffffff ||
gsf->gf_numsrc > sysctl_igmp_max_msf) {
@@
-879,7
+885,7
@@
static int do_ip_setsockopt(struct sock *sk, int level,
msf->imsf_fmode = gsf->gf_fmode;
msf->imsf_numsrc = gsf->gf_numsrc;
err = -EADDRNOTAVAIL;
msf->imsf_fmode = gsf->gf_fmode;
msf->imsf_numsrc = gsf->gf_numsrc;
err = -EADDRNOTAVAIL;
- for (i
=0; i<
gsf->gf_numsrc; ++i) {
+ for (i
= 0; i <
gsf->gf_numsrc; ++i) {
psin = (struct sockaddr_in *)&gsf->gf_slist[i];
if (psin->sin_family != AF_INET)
psin = (struct sockaddr_in *)&gsf->gf_slist[i];
if (psin->sin_family != AF_INET)
@@
-890,17
+896,24
@@
static int do_ip_setsockopt(struct sock *sk, int level,
gsf = NULL;
err = ip_mc_msfilter(sk, msf, ifindex);
gsf = NULL;
err = ip_mc_msfilter(sk, msf, ifindex);
-
mc_msf_out:
+mc_msf_out:
kfree(msf);
kfree(gsf);
break;
}
kfree(msf);
kfree(gsf);
break;
}
+ case IP_MULTICAST_ALL:
+ if (optlen < 1)
+ goto e_inval;
+ if (val != 0 && val != 1)
+ goto e_inval;
+ inet->mc_all = val;
+ break;
case IP_ROUTER_ALERT:
err = ip_ra_control(sk, val ? 1 : 0, NULL);
break;
case IP_FREEBIND:
case IP_ROUTER_ALERT:
err = ip_ra_control(sk, val ? 1 : 0, NULL);
break;
case IP_FREEBIND:
- if (optlen
<
1)
+ if (optlen
<
1)
goto e_inval;
inet->freebind = !!val;
break;
goto e_inval;
inet->freebind = !!val;
break;
@@
-936,7
+949,7
@@
e_inval:
}
int ip_setsockopt(struct sock *sk, int level,
}
int ip_setsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int optlen)
+ int optname, char __user *optval,
unsigned
int optlen)
{
int err;
{
int err;
@@
-957,10
+970,11
@@
int ip_setsockopt(struct sock *sk, int level,
#endif
return err;
}
#endif
return err;
}
+EXPORT_SYMBOL(ip_setsockopt);
#ifdef CONFIG_COMPAT
int compat_ip_setsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_COMPAT
int compat_ip_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
+ char __user *optval,
unsigned
int optlen)
{
int err;
{
int err;
@@
-986,13
+1000,12
@@
int compat_ip_setsockopt(struct sock *sk, int level, int optname,
#endif
return err;
}
#endif
return err;
}
-
EXPORT_SYMBOL(compat_ip_setsockopt);
#endif
/*
EXPORT_SYMBOL(compat_ip_setsockopt);
#endif
/*
- * Get the options. Note for future reference. The GET of IP options gets
the
- * _received_ ones. The set sets the _sent_ ones.
+ * Get the options. Note for future reference. The GET of IP options gets
+ *
the
_received_ ones. The set sets the _sent_ ones.
*/
static int do_ip_getsockopt(struct sock *sk, int level, int optname,
*/
static int do_ip_getsockopt(struct sock *sk, int level, int optname,
@@
-1143,10
+1156,14
@@
static int do_ip_getsockopt(struct sock *sk, int level, int optname,
return -EFAULT;
}
err = ip_mc_gsfget(sk, &gsf,
return -EFAULT;
}
err = ip_mc_gsfget(sk, &gsf,
- (struct group_filter __user *)optval, optlen);
+ (struct group_filter __user *)optval,
+ optlen);
release_sock(sk);
return err;
}
release_sock(sk);
return err;
}
+ case IP_MULTICAST_ALL:
+ val = inet->mc_all;
+ break;
case IP_PKTOPTIONS:
{
struct msghdr msg;
case IP_PKTOPTIONS:
{
struct msghdr msg;
@@
-1163,8
+1180,8
@@
static int do_ip_getsockopt(struct sock *sk, int level, int optname,
if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
struct in_pktinfo info;
if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
struct in_pktinfo info;
- info.ipi_addr.s_addr = inet->rcv_saddr;
- info.ipi_spec_dst.s_addr = inet->rcv_saddr;
+ info.ipi_addr.s_addr = inet->
inet_
rcv_saddr;
+ info.ipi_spec_dst.s_addr = inet->
inet_
rcv_saddr;
info.ipi_ifindex = inet->mc_index;
put_cmsg(&msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
}
info.ipi_ifindex = inet->mc_index;
put_cmsg(&msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
}
@@
-1187,7
+1204,7
@@
static int do_ip_getsockopt(struct sock *sk, int level, int optname,
}
release_sock(sk);
}
release_sock(sk);
- if (len < sizeof(int) && len > 0 && val
>=0 && val<=
255) {
+ if (len < sizeof(int) && len > 0 && val
>= 0 && val <=
255) {
unsigned char ucval = (unsigned char)val;
len = 1;
if (put_user(len, optlen))
unsigned char ucval = (unsigned char)val;
len = 1;
if (put_user(len, optlen))
@@
-1230,6
+1247,7
@@
int ip_getsockopt(struct sock *sk, int level,
#endif
return err;
}
#endif
return err;
}
+EXPORT_SYMBOL(ip_getsockopt);
#ifdef CONFIG_COMPAT
int compat_ip_getsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_COMPAT
int compat_ip_getsockopt(struct sock *sk, int level, int optname,
@@
-1262,11
+1280,5
@@
int compat_ip_getsockopt(struct sock *sk, int level, int optname,
#endif
return err;
}
#endif
return err;
}
-
EXPORT_SYMBOL(compat_ip_getsockopt);
#endif
EXPORT_SYMBOL(compat_ip_getsockopt);
#endif
-
-EXPORT_SYMBOL(ip_cmsg_recv);
-
-EXPORT_SYMBOL(ip_getsockopt);
-EXPORT_SYMBOL(ip_setsockopt);