Lines Matching +full:short +full:- +full:ping

1 // SPDX-License-Identifier: GPL-2.0-or-later
7 * "Ping" sockets
36 #include <linux/bpf-cgroup.h>
38 #include <net/ping.h>
75 return &table->hash[ping_hashfn(net, num, PING_HTABLE_MASK)]; in ping_hashslot()
78 int ping_get_port(struct sock *sk, unsigned short ident) in ping_get_port()
98 if (isk2->inet_num == result) in ping_get_port()
115 /* BUG? Why is this reuse and not reuseaddr? ping.c in ping_get_port()
117 * that other ping processes can steal its packets. in ping_get_port()
119 if ((isk2->inet_num == ident) && in ping_get_port()
121 (!sk2->sk_reuse || !sk->sk_reuse)) in ping_get_port()
127 isk->inet_num = ident; in ping_get_port()
132 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); in ping_get_port()
139 return -EADDRINUSE; in ping_get_port()
145 pr_debug("ping_hash(sk->port=%u)\n", inet_sk(sk)->inet_num); in ping_hash()
155 pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); in ping_unhash()
158 isk->inet_num = 0; in ping_unhash()
159 isk->inet_sport = 0; in ping_unhash()
160 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); in ping_unhash()
174 if (skb->protocol == htons(ETH_P_IP)) { in ping_lookup()
178 (int)ident, &ip_hdr(skb)->daddr, dif); in ping_lookup()
180 } else if (skb->protocol == htons(ETH_P_IPV6)) { in ping_lookup()
184 (int)ident, &ipv6_hdr(skb)->daddr, dif); in ping_lookup()
194 if (isk->inet_num != ident) in ping_lookup()
197 if (skb->protocol == htons(ETH_P_IP) && in ping_lookup()
198 sk->sk_family == AF_INET) { in ping_lookup()
200 (int) isk->inet_num, &isk->inet_rcv_saddr, in ping_lookup()
201 sk->sk_bound_dev_if); in ping_lookup()
203 if (isk->inet_rcv_saddr && in ping_lookup()
204 isk->inet_rcv_saddr != ip_hdr(skb)->daddr) in ping_lookup()
207 } else if (skb->protocol == htons(ETH_P_IPV6) && in ping_lookup()
208 sk->sk_family == AF_INET6) { in ping_lookup()
211 (int) isk->inet_num, in ping_lookup()
212 &sk->sk_v6_rcv_saddr, in ping_lookup()
213 sk->sk_bound_dev_if); in ping_lookup()
215 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && in ping_lookup()
216 !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, in ping_lookup()
217 &ipv6_hdr(skb)->daddr)) in ping_lookup()
224 if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && in ping_lookup()
225 sk->sk_bound_dev_if != sdif) in ping_lookup()
240 kgid_t *data = net->ipv4.ping_group_range.range; in inet_get_ping_group_range_net()
244 seq = read_seqbegin(&net->ipv4.ping_group_range.lock); in inet_get_ping_group_range_net()
248 } while (read_seqretry(&net->ipv4.ping_group_range.lock, seq)); in inet_get_ping_group_range_net()
261 if (sk->sk_family == AF_INET6) in ping_init_sock()
262 sk->sk_ipv6only = 1; in ping_init_sock()
269 for (i = 0; i < group_info->ngroups; i++) { in ping_init_sock()
270 kgid_t gid = group_info->gid[i]; in ping_init_sock()
276 ret = -EACCES; in ping_init_sock()
286 pr_debug("ping_close(sk=%p,sk->num=%u)\n", in ping_close()
287 inet_sk(sk), inet_sk(sk)->inet_num); in ping_close()
288 pr_debug("isk->refcnt = %d\n", refcount_read(&sk->sk_refcnt)); in ping_close()
302 return -EINVAL; in ping_pre_connect()
307 /* Checks the bind address and possibly modifies sk->sk_bound_dev_if. */
312 if (sk->sk_family == AF_INET) { in ping_check_bind_addr()
318 return -EINVAL; in ping_check_bind_addr()
320 if (addr->sin_family != AF_INET && in ping_check_bind_addr()
321 !(addr->sin_family == AF_UNSPEC && in ping_check_bind_addr()
322 addr->sin_addr.s_addr == htonl(INADDR_ANY))) in ping_check_bind_addr()
323 return -EAFNOSUPPORT; in ping_check_bind_addr()
326 sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port)); in ping_check_bind_addr()
328 if (addr->sin_addr.s_addr == htonl(INADDR_ANY)) in ping_check_bind_addr()
331 tb_id = l3mdev_fib_table_by_index(net, sk->sk_bound_dev_if) ? : tb_id; in ping_check_bind_addr()
332 chk_addr_ret = inet_addr_type_table(net, addr->sin_addr.s_addr, tb_id); in ping_check_bind_addr()
338 return -EADDRNOTAVAIL; in ping_check_bind_addr()
341 } else if (sk->sk_family == AF_INET6) { in ping_check_bind_addr()
347 return -EINVAL; in ping_check_bind_addr()
349 if (addr->sin6_family != AF_INET6) in ping_check_bind_addr()
350 return -EAFNOSUPPORT; in ping_check_bind_addr()
353 sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port)); in ping_check_bind_addr()
355 addr_type = ipv6_addr_type(&addr->sin6_addr); in ping_check_bind_addr()
359 (scoped && !addr->sin6_scope_id)) in ping_check_bind_addr()
360 return -EINVAL; in ping_check_bind_addr()
363 if (addr->sin6_scope_id) { in ping_check_bind_addr()
364 dev = dev_get_by_index_rcu(net, addr->sin6_scope_id); in ping_check_bind_addr()
367 return -ENODEV; in ping_check_bind_addr()
371 if (!dev && sk->sk_bound_dev_if) { in ping_check_bind_addr()
372 dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if); in ping_check_bind_addr()
375 return -ENODEV; in ping_check_bind_addr()
378 has_addr = pingv6_ops.ipv6_chk_addr(net, &addr->sin6_addr, dev, in ping_check_bind_addr()
384 return -EADDRNOTAVAIL; in ping_check_bind_addr()
387 sk->sk_bound_dev_if = addr->sin6_scope_id; in ping_check_bind_addr()
390 return -EAFNOSUPPORT; in ping_check_bind_addr()
397 if (saddr->sa_family == AF_INET) { in ping_set_saddr()
400 isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr; in ping_set_saddr()
402 } else if (saddr->sa_family == AF_INET6) { in ping_set_saddr()
405 sk->sk_v6_rcv_saddr = np->saddr = addr->sin6_addr; in ping_set_saddr()
412 * Moreover, we don't allow binding to multi- and broadcast addresses.
418 unsigned short snum; in ping_bind()
420 int dif = sk->sk_bound_dev_if; in ping_bind()
428 err = -EINVAL; in ping_bind()
429 if (isk->inet_num != 0) in ping_bind()
432 err = -EADDRINUSE; in ping_bind()
433 snum = ntohs(((struct sockaddr_in *)uaddr)->sin_port); in ping_bind()
435 /* Restore possibly modified sk->sk_bound_dev_if by ping_check_bind_addr(). */ in ping_bind()
436 sk->sk_bound_dev_if = dif; in ping_bind()
442 isk->inet_num, in ping_bind()
443 sk->sk_bound_dev_if); in ping_bind()
446 if (sk->sk_family == AF_INET && isk->inet_rcv_saddr) in ping_bind()
447 sk->sk_userlocks |= SOCK_BINDADDR_LOCK; in ping_bind()
449 if (sk->sk_family == AF_INET6 && !ipv6_addr_any(&sk->sk_v6_rcv_saddr)) in ping_bind()
450 sk->sk_userlocks |= SOCK_BINDADDR_LOCK; in ping_bind()
454 sk->sk_userlocks |= SOCK_BINDPORT_LOCK; in ping_bind()
455 isk->inet_sport = htons(isk->inet_num); in ping_bind()
456 isk->inet_daddr = 0; in ping_bind()
457 isk->inet_dport = 0; in ping_bind()
460 if (sk->sk_family == AF_INET6) in ping_bind()
461 memset(&sk->sk_v6_daddr, 0, sizeof(sk->sk_v6_daddr)); in ping_bind()
467 pr_debug("ping_v4_bind -> %d\n", err); in ping_bind()
496 struct net *net = dev_net(skb->dev); in ping_err()
501 if (skb->protocol == htons(ETH_P_IP)) { in ping_err()
503 type = icmp_hdr(skb)->type; in ping_err()
504 code = icmp_hdr(skb)->code; in ping_err()
505 icmph = (struct icmphdr *)(skb->data + offset); in ping_err()
506 } else if (skb->protocol == htons(ETH_P_IPV6)) { in ping_err()
508 type = icmp6_hdr(skb)->icmp6_type; in ping_err()
509 code = icmp6_hdr(skb)->icmp6_code; in ping_err()
510 icmph = (struct icmphdr *) (skb->data + offset); in ping_err()
517 if (!ping_supported(family, icmph->type, icmph->code)) in ping_err()
521 skb->protocol, type, code, ntohs(icmph->un.echo.id), in ping_err()
522 ntohs(icmph->un.echo.sequence)); in ping_err()
524 sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id)); in ping_err()
535 if (skb->protocol == htons(ETH_P_IP)) { in ping_err()
542 /* This is not a real error but ping wants to see it. in ping_err()
554 if (READ_ONCE(inet_sock->pmtudisc) != IP_PMTUDISC_DONT) { in ping_err()
574 } else if (skb->protocol == htons(ETH_P_IPV6)) { in ping_err()
585 if (!harderr || sk->sk_state != TCP_ESTABLISHED) in ping_err()
598 sk->sk_err = err; in ping_err()
615 if (!csum_and_copy_from_iter_full(to, fraglen, &pfh->wcheck, in ping_getfrag()
616 &pfh->msg->msg_iter)) in ping_getfrag()
617 return -EFAULT; in ping_getfrag()
624 if (pfh->family == AF_INET6) { in ping_getfrag()
625 skb->csum = csum_block_add(skb->csum, pfh->wcheck, odd); in ping_getfrag()
626 skb->ip_summed = CHECKSUM_NONE; in ping_getfrag()
627 pfh->wcheck = 0; in ping_getfrag()
638 struct sk_buff *skb = skb_peek(&sk->sk_write_queue); in ping_v4_push_pending_frames()
642 pfh->wcheck = csum_partial((char *)&pfh->icmph, in ping_v4_push_pending_frames()
643 sizeof(struct icmphdr), pfh->wcheck); in ping_v4_push_pending_frames()
644 pfh->icmph.checksum = csum_fold(pfh->wcheck); in ping_v4_push_pending_frames()
645 memcpy(icmp_hdr(skb), &pfh->icmph, sizeof(struct icmphdr)); in ping_v4_push_pending_frames()
646 skb->ip_summed = CHECKSUM_NONE; in ping_v4_push_pending_frames()
656 return -EMSGSIZE; in ping_common_sendmsg()
660 return -EINVAL; in ping_common_sendmsg()
667 if (msg->msg_flags & MSG_OOB) in ping_common_sendmsg()
668 return -EOPNOTSUPP; in ping_common_sendmsg()
675 return -EFAULT; in ping_common_sendmsg()
678 type = ((struct icmphdr *) user_icmph)->type; in ping_common_sendmsg()
679 code = ((struct icmphdr *) user_icmph)->code; in ping_common_sendmsg()
682 type = ((struct icmp6hdr *) user_icmph)->icmp6_type; in ping_common_sendmsg()
683 code = ((struct icmp6hdr *) user_icmph)->icmp6_code; in ping_common_sendmsg()
690 return -EINVAL; in ping_common_sendmsg()
711 pr_debug("ping_v4_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num); in ping_v4_sendmsg()
722 if (msg->msg_name) { in ping_v4_sendmsg()
723 DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name); in ping_v4_sendmsg()
724 if (msg->msg_namelen < sizeof(*usin)) in ping_v4_sendmsg()
725 return -EINVAL; in ping_v4_sendmsg()
726 if (usin->sin_family != AF_INET) in ping_v4_sendmsg()
727 return -EAFNOSUPPORT; in ping_v4_sendmsg()
728 daddr = usin->sin_addr.s_addr; in ping_v4_sendmsg()
731 if (sk->sk_state != TCP_ESTABLISHED) in ping_v4_sendmsg()
732 return -EDESTADDRREQ; in ping_v4_sendmsg()
733 daddr = inet->inet_daddr; in ping_v4_sendmsg()
739 if (msg->msg_controllen) { in ping_v4_sendmsg()
752 inet_opt = rcu_dereference(inet->inet_opt); in ping_v4_sendmsg()
755 sizeof(*inet_opt) + inet_opt->opt.optlen); in ping_v4_sendmsg()
764 if (ipc.opt && ipc.opt->opt.srr) { in ping_v4_sendmsg()
766 err = -EINVAL; in ping_v4_sendmsg()
769 faddr = ipc.opt->opt.faddr; in ping_v4_sendmsg()
776 ipc.oif = READ_ONCE(inet->mc_index); in ping_v4_sendmsg()
778 saddr = READ_ONCE(inet->mc_addr); in ping_v4_sendmsg()
780 ipc.oif = READ_ONCE(inet->uc_index); in ping_v4_sendmsg()
783 sk->sk_protocol, inet_sk_flowi_flags(sk), faddr, in ping_v4_sendmsg()
784 saddr, 0, 0, sk->sk_uid); in ping_v4_sendmsg()
794 if (err == -ENETUNREACH) in ping_v4_sendmsg()
799 err = -EACCES; in ping_v4_sendmsg()
800 if ((rt->rt_flags & RTCF_BROADCAST) && in ping_v4_sendmsg()
804 if (msg->msg_flags & MSG_CONFIRM) in ping_v4_sendmsg()
816 pfh.icmph.un.echo.id = inet->inet_sport; in ping_v4_sendmsg()
824 msg->msg_flags); in ping_v4_sendmsg()
843 if (msg->msg_flags & MSG_PROBE) in ping_v4_sendmsg()
844 dst_confirm_neigh(&rt->dst, &fl4.daddr); in ping_v4_sendmsg()
845 if (!(msg->msg_flags & MSG_PROBE) || len) in ping_v4_sendmsg()
855 int family = sk->sk_family; in ping_recvmsg()
859 pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); in ping_recvmsg()
861 err = -EOPNOTSUPP; in ping_recvmsg()
872 copied = skb->len; in ping_recvmsg()
874 msg->msg_flags |= MSG_TRUNC; in ping_recvmsg()
887 DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); in ping_recvmsg()
890 sin->sin_family = AF_INET; in ping_recvmsg()
891 sin->sin_port = 0 /* skb->h.uh->source */; in ping_recvmsg()
892 sin->sin_addr.s_addr = ip_hdr(skb)->saddr; in ping_recvmsg()
893 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); in ping_recvmsg()
903 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); in ping_recvmsg()
906 sin6->sin6_family = AF_INET6; in ping_recvmsg()
907 sin6->sin6_port = 0; in ping_recvmsg()
908 sin6->sin6_addr = ip6->saddr; in ping_recvmsg()
909 sin6->sin6_flowinfo = 0; in ping_recvmsg()
911 sin6->sin6_flowinfo = ip6_flowinfo(ip6); in ping_recvmsg()
912 sin6->sin6_scope_id = in ping_recvmsg()
913 ipv6_iface_scope_id(&sin6->sin6_addr, in ping_recvmsg()
918 if (inet6_sk(sk)->rxopt.all) in ping_recvmsg()
920 if (skb->protocol == htons(ETH_P_IPV6) && in ping_recvmsg()
921 inet6_sk(sk)->rxopt.all) in ping_recvmsg()
923 else if (skb->protocol == htons(ETH_P_IP) && in ping_recvmsg()
936 pr_debug("ping_recvmsg -> %d\n", err); in ping_recvmsg()
946 pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n", in __ping_queue_rcv_skb()
947 inet_sk(sk), inet_sk(sk)->inet_num, skb); in __ping_queue_rcv_skb()
950 pr_debug("ping_queue_rcv_skb -> failed\n"); in __ping_queue_rcv_skb()
958 return __ping_queue_rcv_skb(sk, skb) ? -1 : 0; in ping_queue_rcv_skb()
971 struct net *net = dev_net(skb->dev); in ping_rcv()
977 skb, ntohs(icmph->un.echo.id), ntohs(icmph->un.echo.sequence)); in ping_rcv()
980 skb_push(skb, skb->data - (u8 *)icmph); in ping_rcv()
982 sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id)); in ping_rcv()
1001 .name = "PING",
1028 struct ping_iter_state *state = seq->private; in ping_get_first()
1031 for (state->bucket = start; state->bucket < PING_HTABLE_SIZE; in ping_get_first()
1032 ++state->bucket) { in ping_get_first()
1035 hslot = &ping_table.hash[state->bucket]; in ping_get_first()
1042 sk->sk_family == state->family) in ping_get_first()
1053 struct ping_iter_state *state = seq->private; in ping_get_next()
1061 return ping_get_first(seq, state->bucket + 1); in ping_get_next()
1071 --pos; in ping_get_idx()
1078 struct ping_iter_state *state = seq->private; in ping_seq_start()
1079 state->bucket = 0; in ping_seq_start()
1080 state->family = family; in ping_seq_start()
1084 return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN; in ping_seq_start()
1118 __be32 dest = inet->inet_daddr; in ping_v4_format_sock()
1119 __be32 src = inet->inet_rcv_saddr; in ping_v4_format_sock()
1120 __u16 destp = ntohs(inet->inet_dport); in ping_v4_format_sock()
1121 __u16 srcp = ntohs(inet->inet_sport); in ping_v4_format_sock()
1125 bucket, src, srcp, dest, destp, sp->sk_state, in ping_v4_format_sock()
1131 refcount_read(&sp->sk_refcnt), sp, in ping_v4_format_sock()
1132 atomic_read(&sp->sk_drops)); in ping_v4_format_sock()
1140 "rx_queue tr tm->when retrnsmt uid timeout " in ping_v4_seq_show()
1143 struct ping_iter_state *state = seq->private; in ping_v4_seq_show()
1145 ping_v4_format_sock(v, seq, state->bucket); in ping_v4_seq_show()
1160 if (!proc_create_net("icmp", 0444, net->proc_net, &ping_v4_seq_ops, in ping_v4_proc_init_net()
1162 return -ENOMEM; in ping_v4_proc_init_net()
1168 remove_proc_entry("icmp", net->proc_net); in ping_v4_proc_exit_net()