#define IP_CMSG_TOS 4
#define IP_CMSG_RECVOPTS 8
#define IP_CMSG_RETOPTS 16
-#define IP_CMSG_PASSSEC 32
/*
* SOL_IP control messages.
put_cmsg(msg, SOL_IP, IP_RETOPTS, opt->optlen, opt->__data);
}
-static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
-{
- char *secdata;
- u32 seclen;
- int err;
-
- err = security_socket_getpeersec_dgram(skb, &secdata, &seclen);
- if (err)
- return;
-
- put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
-}
-
void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
{
if (flags & 1)
ip_cmsg_recv_retopts(msg, skb);
- if ((flags>>=1) == 0)
- return;
-
- if (flags & 1)
- ip_cmsg_recv_security(msg, skb);
}
int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc)
* an IP socket.
*/
-static int do_ip_setsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int optlen)
+int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen)
{
struct inet_sock *inet = inet_sk(sk);
int val=0,err;
+ if (level != SOL_IP)
+ return -ENOPROTOOPT;
+
if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
(1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
(1<<IP_RETOPTS) | (1<<IP_TOS) |
(1<<IP_TTL) | (1<<IP_HDRINCL) |
(1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
- (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
- (1<<IP_PASSSEC))) ||
+ (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND))) ||
optname == IP_MULTICAST_TTL ||
optname == IP_MULTICAST_LOOP) {
if (optlen >= sizeof(int)) {
else
inet->cmsg_flags &= ~IP_CMSG_RETOPTS;
break;
- case IP_PASSSEC:
- if (val)
- inet->cmsg_flags |= IP_CMSG_PASSSEC;
- else
- inet->cmsg_flags &= ~IP_CMSG_PASSSEC;
- break;
case IP_TOS: /* This sets both TOS and Precedence */
if (sk->sk_type == SOCK_STREAM) {
val &= ~3;
break;
default:
+#ifdef CONFIG_NETFILTER
+ err = nf_setsockopt(sk, PF_INET, optname, optval,
+ optlen);
+#else
err = -ENOPROTOOPT;
+#endif
break;
}
release_sock(sk);
return -EINVAL;
}
-int ip_setsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int optlen)
-{
- int err;
-
- if (level != SOL_IP)
- return -ENOPROTOOPT;
-
- err = do_ip_setsockopt(sk, level, optname, optval, optlen);
-#ifdef CONFIG_NETFILTER
- /* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
- optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY
-#ifdef CONFIG_IP_MROUTE
- && (optname < MRT_BASE || optname > (MRT_BASE + 10))
-#endif
- ) {
- lock_sock(sk);
- err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
- release_sock(sk);
- }
-#endif
- return err;
-}
-
-#ifdef CONFIG_COMPAT
-int compat_ip_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int optlen)
-{
- int err;
-
- if (level != SOL_IP)
- return -ENOPROTOOPT;
-
- err = do_ip_setsockopt(sk, level, optname, optval, optlen);
-#ifdef CONFIG_NETFILTER
- /* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
- optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY
-#ifdef CONFIG_IP_MROUTE
- && (optname < MRT_BASE || optname > (MRT_BASE + 10))
-#endif
- ) {
- lock_sock(sk);
- err = compat_nf_setsockopt(sk, PF_INET, optname,
- optval, optlen);
- release_sock(sk);
- }
-#endif
- return err;
-}
-
-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.
*/
-static int do_ip_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
+int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen)
{
struct inet_sock *inet = inet_sk(sk);
int val;
case IP_RETOPTS:
val = (inet->cmsg_flags & IP_CMSG_RETOPTS) != 0;
break;
- case IP_PASSSEC:
- val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
- break;
case IP_TOS:
val = inet->tos;
break;
val = inet->freebind;
break;
default:
+#ifdef CONFIG_NETFILTER
+ val = nf_getsockopt(sk, PF_INET, optname, optval,
+ &len);
+ release_sock(sk);
+ if (val >= 0)
+ val = put_user(len, optlen);
+ return val;
+#else
release_sock(sk);
return -ENOPROTOOPT;
+#endif
}
release_sock(sk);
return 0;
}
-int ip_getsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int __user *optlen)
-{
- int err;
-
- err = do_ip_getsockopt(sk, level, optname, optval, optlen);
-#ifdef CONFIG_NETFILTER
- /* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS
-#ifdef CONFIG_IP_MROUTE
- && (optname < MRT_BASE || optname > MRT_BASE+10)
-#endif
- ) {
- int len;
-
- if(get_user(len,optlen))
- return -EFAULT;
-
- lock_sock(sk);
- err = nf_getsockopt(sk, PF_INET, optname, optval,
- &len);
- release_sock(sk);
- if (err >= 0)
- err = put_user(len, optlen);
- return err;
- }
-#endif
- return err;
-}
-
-#ifdef CONFIG_COMPAT
-int compat_ip_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
-{
- int err = do_ip_getsockopt(sk, level, optname, optval, optlen);
-#ifdef CONFIG_NETFILTER
- /* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS
-#ifdef CONFIG_IP_MROUTE
- && (optname < MRT_BASE || optname > MRT_BASE+10)
-#endif
- ) {
- int len;
-
- if (get_user(len, optlen))
- return -EFAULT;
-
- lock_sock(sk);
- err = compat_nf_getsockopt(sk, PF_INET, optname, optval, &len);
- release_sock(sk);
- if (err >= 0)
- err = put_user(len, optlen);
- return err;
- }
-#endif
- return err;
-}
-
-EXPORT_SYMBOL(compat_ip_getsockopt);
-#endif
-
EXPORT_SYMBOL(ip_cmsg_recv);
EXPORT_SYMBOL(ip_getsockopt);