diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2013-05-22 16:17:31 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-26 00:07:49 -0400 |
commit | 6d0bfe22611602f36617bc7aa2ffa1bbb2f54c67 (patch) | |
tree | 140f06221a5da5c44526cb61f921d80fec2132c2 /include/net/ping.h | |
parent | 6e2842f4bbb5abcf57d3cb0f10870e0ce20c0ba2 (diff) |
net: ipv6: Add IPv6 support to the ping socket.
This adds the ability to send ICMPv6 echo requests without a
raw socket. The equivalent ability for ICMPv4 was added in
2011.
Instead of having separate code paths for IPv4 and IPv6, make
most of the code in net/ipv4/ping.c dual-stack and only add a
few IPv6-specific bits (like the protocol definition) to a new
net/ipv6/ping.c. Hopefully this will reduce divergence and/or
duplication of bugs in the future.
Caveats:
- Setting options via ancillary data (e.g., using IPV6_PKTINFO
to specify the outgoing interface) is not yet supported.
- There are no separate security settings for IPv4 and IPv6;
everything is controlled by /proc/net/ipv4/ping_group_range.
- The proc interface does not yet display IPv6 ping sockets
properly.
Tested with a patched copy of ping6 and using raw socket calls.
Compiles and works with all of CONFIG_IPV6={n,m,y}.
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/ping.h')
-rw-r--r-- | include/net/ping.h | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/include/net/ping.h b/include/net/ping.h index 682b5ae9af51..9242fa090d3d 100644 --- a/include/net/ping.h +++ b/include/net/ping.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #ifndef _PING_H | 13 | #ifndef _PING_H |
14 | #define _PING_H | 14 | #define _PING_H |
15 | 15 | ||
16 | #include <net/icmp.h> | ||
16 | #include <net/netns/hash.h> | 17 | #include <net/netns/hash.h> |
17 | 18 | ||
18 | /* PING_HTABLE_SIZE must be power of 2 */ | 19 | /* PING_HTABLE_SIZE must be power of 2 */ |
@@ -28,6 +29,18 @@ | |||
28 | */ | 29 | */ |
29 | #define GID_T_MAX (((gid_t)~0U) >> 1) | 30 | #define GID_T_MAX (((gid_t)~0U) >> 1) |
30 | 31 | ||
32 | /* Compatibility glue so we can support IPv6 when it's compiled as a module */ | ||
33 | struct pingv6_ops { | ||
34 | int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len); | ||
35 | int (*ip6_datagram_recv_ctl)(struct sock *sk, struct msghdr *msg, | ||
36 | struct sk_buff *skb); | ||
37 | int (*icmpv6_err_convert)(u8 type, u8 code, int *err); | ||
38 | void (*ipv6_icmp_error)(struct sock *sk, struct sk_buff *skb, int err, | ||
39 | __be16 port, u32 info, u8 *payload); | ||
40 | int (*ipv6_chk_addr)(struct net *net, const struct in6_addr *addr, | ||
41 | struct net_device *dev, int strict); | ||
42 | }; | ||
43 | |||
31 | struct ping_table { | 44 | struct ping_table { |
32 | struct hlist_nulls_head hash[PING_HTABLE_SIZE]; | 45 | struct hlist_nulls_head hash[PING_HTABLE_SIZE]; |
33 | rwlock_t lock; | 46 | rwlock_t lock; |
@@ -39,10 +52,39 @@ struct ping_iter_state { | |||
39 | }; | 52 | }; |
40 | 53 | ||
41 | extern struct proto ping_prot; | 54 | extern struct proto ping_prot; |
55 | extern struct ping_table ping_table; | ||
56 | #if IS_ENABLED(CONFIG_IPV6) | ||
57 | extern struct pingv6_ops pingv6_ops; | ||
58 | #endif | ||
42 | 59 | ||
60 | struct pingfakehdr { | ||
61 | struct icmphdr icmph; | ||
62 | struct iovec *iov; | ||
63 | sa_family_t family; | ||
64 | __wsum wcheck; | ||
65 | }; | ||
43 | 66 | ||
44 | extern void ping_rcv(struct sk_buff *); | 67 | int ping_get_port(struct sock *sk, unsigned short ident); |
45 | extern void ping_err(struct sk_buff *, u32 info); | 68 | void ping_hash(struct sock *sk); |
69 | void ping_unhash(struct sock *sk); | ||
70 | |||
71 | int ping_init_sock(struct sock *sk); | ||
72 | void ping_close(struct sock *sk, long timeout); | ||
73 | int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len); | ||
74 | void ping_err(struct sk_buff *skb, int offset, u32 info); | ||
75 | int ping_getfrag(void *from, char *to, int offset, int fraglen, int odd, | ||
76 | struct sk_buff *); | ||
77 | |||
78 | int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | ||
79 | size_t len, int noblock, int flags, int *addr_len); | ||
80 | int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, | ||
81 | void *user_icmph, size_t icmph_len); | ||
82 | int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | ||
83 | size_t len); | ||
84 | int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | ||
85 | size_t len); | ||
86 | int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); | ||
87 | void ping_rcv(struct sk_buff *skb); | ||
46 | 88 | ||
47 | #ifdef CONFIG_PROC_FS | 89 | #ifdef CONFIG_PROC_FS |
48 | extern int __init ping_proc_init(void); | 90 | extern int __init ping_proc_init(void); |
@@ -50,6 +92,7 @@ extern void ping_proc_exit(void); | |||
50 | #endif | 92 | #endif |
51 | 93 | ||
52 | void __init ping_init(void); | 94 | void __init ping_init(void); |
53 | 95 | int __init pingv6_init(void); | |
96 | void pingv6_exit(void); | ||
54 | 97 | ||
55 | #endif /* _PING_H */ | 98 | #endif /* _PING_H */ |