18 #include <linux/module.h>
19 #include <linux/types.h>
23 #include <linux/icmp.h>
25 #include <linux/netdevice.h>
26 #include <linux/slab.h>
31 #include <linux/udp.h>
32 #include <linux/igmp.h>
33 #include <linux/netfilter.h>
35 #include <linux/mroute.h>
40 #if IS_ENABLED(CONFIG_IPV6)
45 #include <linux/errqueue.h>
46 #include <asm/uaccess.h>
48 #define IP_CMSG_PKTINFO 1
51 #define IP_CMSG_RECVOPTS 8
52 #define IP_CMSG_RETOPTS 16
53 #define IP_CMSG_PASSSEC 32
54 #define IP_CMSG_ORIGDSTADDR 64
59 #define PKTINFO_SKB_CB(__skb) ((struct in_pktinfo *)((__skb)->cb))
65 info.
ipi_addr.s_addr = ip_hdr(skb)->daddr;
72 int ttl = ip_hdr(skb)->ttl;
76 static void ip_cmsg_recv_tos(
struct msghdr *msg,
struct sk_buff *skb)
81 static void ip_cmsg_recv_opts(
struct msghdr *msg,
struct sk_buff *skb)
91 static void ip_cmsg_recv_retopts(
struct msghdr *msg,
struct sk_buff *skb)
93 unsigned char optbuf[
sizeof(
struct ip_options) + 40];
96 if (
IPCB(skb)->opt.optlen == 0)
108 static void ip_cmsg_recv_security(
struct msghdr *msg,
struct sk_buff *skb)
114 err = security_socket_getpeersec_dgram(
NULL, skb, &secid);
126 static void ip_cmsg_recv_dstaddr(
struct msghdr *msg,
struct sk_buff *skb)
129 const struct iphdr *iph = ip_hdr(skb);
132 if (skb_transport_offset(skb) + 4 > skb->
len)
141 sin.sin_addr.s_addr = iph->
daddr;
142 sin.sin_port = ports[1];
143 memset(sin.sin_zero, 0,
sizeof(sin.sin_zero));
155 ip_cmsg_recv_pktinfo(msg, skb);
156 if ((flags >>= 1) == 0)
160 ip_cmsg_recv_ttl(msg, skb);
161 if ((flags >>= 1) == 0)
165 ip_cmsg_recv_tos(msg, skb);
166 if ((flags >>= 1) == 0)
170 ip_cmsg_recv_opts(msg, skb);
171 if ((flags >>= 1) == 0)
175 ip_cmsg_recv_retopts(msg, skb);
176 if ((flags >>= 1) == 0)
180 ip_cmsg_recv_security(msg, skb);
182 if ((flags >>= 1) == 0)
185 ip_cmsg_recv_dstaddr(msg, skb);
204 err < 40 ? err : 40);
251 struct ip_ra_chain *
ra, *new_ra;
252 struct ip_ra_chain __rcu **rap;
259 spin_lock_bh(&ip_ra_lock);
260 for (rap = &ip_ra_chain;
262 lockdep_is_held(&ip_ra_lock))) !=
NULL;
266 spin_unlock_bh(&ip_ra_lock);
273 spin_unlock_bh(&ip_ra_lock);
287 if (new_ra ==
NULL) {
288 spin_unlock_bh(&ip_ra_lock);
297 spin_unlock_bh(&ip_ra_lock);
312 serr->
ee.ee_errno =
err;
314 serr->
ee.ee_type = icmp_hdr(skb)->type;
315 serr->
ee.ee_code = icmp_hdr(skb)->code;
318 serr->
ee.ee_data = 0;
320 skb_network_header(skb);
324 skb_reset_transport_header(skb);
346 skb_reset_network_header(skb);
351 serr->
ee.ee_errno =
err;
353 serr->
ee.ee_type = 0;
354 serr->
ee.ee_code = 0;
357 serr->
ee.ee_data = 0;
361 __skb_pull(skb, skb_tail_pointer(skb) - skb->
data);
362 skb_reset_transport_header(skb);
397 sock_recv_timestamp(msg, sk, skb);
407 memset(&sin->sin_zero, 0,
sizeof(sin->sin_zero));
411 sin = &errhdr.offender;
417 sin->
sin_addr.s_addr = ip_hdr(skb)->saddr;
419 memset(&sin->sin_zero, 0,
sizeof(sin->sin_zero));
454 static int do_ip_setsockopt(
struct sock *sk,
int level,
455 int optname,
char __user *optval,
unsigned int optlen)
482 if (optlen >=
sizeof(
int)) {
483 if (
get_user(val, (
int __user *) optval))
485 }
else if (optlen >=
sizeof(
char)) {
488 if (
get_user(ucval, (
unsigned char __user *) optval))
496 if (ip_mroute_opt(optname))
517 #if IS_ENABLED(CONFIG_IPV6)
518 if (sk->sk_family ==
PF_INET ||
519 (!((1 << sk->sk_state) &
528 #if IS_ENABLED(CONFIG_IPV6)
584 if (inet->
tos != val) {
593 if (val != -1 && (val < 0 || val > 255))
628 if (val < 0 || val > 255)
642 if (optlen !=
sizeof(
int))
659 if (sk->sk_bound_dev_if)
677 if (optlen <
sizeof(
struct in_addr))
681 if (optlen >=
sizeof(
struct ip_mreqn)) {
685 memset(&mreq, 0,
sizeof(mreq));
686 if (optlen >=
sizeof(
struct ip_mreq)) {
690 }
else if (optlen >=
sizeof(
struct in_addr)) {
697 if (!mreq.imr_ifindex) {
704 dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
706 mreq.imr_ifindex = dev->
ifindex;
717 if (sk->sk_bound_dev_if &&
718 mreq.imr_ifindex != sk->sk_bound_dev_if)
722 inet->
mc_addr = mreq.imr_address.s_addr;
733 if (inet_sk(sk)->is_icsk)
736 if (optlen <
sizeof(
struct ip_mreq))
739 if (optlen >=
sizeof(
struct ip_mreqn)) {
743 memset(&mreq, 0,
sizeof(mreq));
760 if (optlen > sysctl_optmem_max) {
814 mreq.imr_address.s_addr = mreqs.imr_interface;
815 mreq.imr_ifindex = 0;
843 memset(&mreq, 0,
sizeof(mreq));
844 mreq.imr_multiaddr = psin->
sin_addr;
845 mreq.imr_ifindex = greq.gr_interface;
869 if (greqs.gsr_group.ss_family !=
AF_INET ||
870 greqs.gsr_source.ss_family !=
AF_INET) {
875 mreqs.imr_multiaddr = psin->
sin_addr.s_addr;
877 mreqs.imr_sourceaddr = psin->
sin_addr.s_addr;
878 mreqs.imr_interface = 0;
890 mreq.imr_multiaddr = psin->
sin_addr;
891 mreq.imr_address.s_addr = 0;
892 mreq.imr_ifindex = greqs.gsr_interface;
896 greqs.gsr_interface = mreq.imr_ifindex;
904 greqs.gsr_interface);
912 int msize,
i, ifindex;
916 if (optlen > sysctl_optmem_max) {
975 if (val != 0 && val != 1)
1010 if (val < 0 || val > 255)
1040 if (skb_rtable(skb)) {
1051 int optname,
char __user *optval,
unsigned int optlen)
1058 err = do_ip_setsockopt(sk, level, optname, optval, optlen);
1059 #ifdef CONFIG_NETFILTER
1064 !ip_mroute_opt(optname)) {
1074 #ifdef CONFIG_COMPAT
1076 char __user *optval,
unsigned int optlen)
1087 err = do_ip_setsockopt(sk, level, optname, optval, optlen);
1088 #ifdef CONFIG_NETFILTER
1093 !ip_mroute_opt(optname)) {
1095 err = compat_nf_setsockopt(sk,
PF_INET, optname,
1110 static int do_ip_getsockopt(
struct sock *sk,
int level,
int optname,
1111 char __user *optval,
int __user *optlen,
unsigned int flags)
1120 if (ip_mroute_opt(optname))
1133 unsigned char optbuf[
sizeof(
struct ip_options)+40];
1143 inet_opt->
opt.optlen);
1183 val = (inet->
uc_ttl == -1 ?
1200 dst = sk_dst_get(sk);
1226 len =
min_t(
unsigned int, len,
sizeof(
struct in_addr));
1292 info.ipi_addr.s_addr = inet->inet_rcv_saddr;
1293 info.ipi_spec_dst.s_addr = inet->inet_rcv_saddr;
1323 if (len <
sizeof(
int) && len > 0 && val >= 0 && val <= 255) {
1324 unsigned char ucval = (
unsigned char)val;
1331 len =
min_t(
unsigned int,
sizeof(
int), len);
1341 int optname,
char __user *optval,
int __user *optlen)
1345 err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0);
1346 #ifdef CONFIG_NETFILTER
1349 !ip_mroute_opt(optname)) {
1368 #ifdef CONFIG_COMPAT
1370 char __user *optval,
int __user *optlen)
1378 err = do_ip_getsockopt(sk, level, optname, optval, optlen,
1381 #ifdef CONFIG_NETFILTER
1384 !ip_mroute_opt(optname)) {
1391 err = compat_nf_getsockopt(sk,
PF_INET, optname, optval, &len);