2019-05-27 08:55:01 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
[INET_DIAG]: Move the tcp_diag interface to the proper place
With this the previous setup is back, i.e. tcp_diag can be built as a module,
as dccp_diag and both share the infrastructure available in inet_diag.
If one selects CONFIG_INET_DIAG as module CONFIG_INET_TCP_DIAG will also be
built as a module, as will CONFIG_INET_DCCP_DIAG, if CONFIG_IP_DCCP was
selected static or as a module, if CONFIG_INET_DIAG is y, being statically
linked CONFIG_INET_TCP_DIAG will follow suit and CONFIG_INET_DCCP_DIAG will be
built in the same manner as CONFIG_IP_DCCP.
Now to aim at UDP, converting it to use inet_hashinfo, so that we can use
iproute2 for UDP sockets as well.
Ah, just to show an example of this new infrastructure working for DCCP :-)
[root@qemu ~]# ./ss -dane
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 0 *:5001 *:* ino:942 sk:cfd503a0
ESTAB 0 0 127.0.0.1:5001 127.0.0.1:32770 ino:943 sk:cfd50a60
ESTAB 0 0 127.0.0.1:32770 127.0.0.1:5001 ino:947 sk:cfd50700
TIME-WAIT 0 0 127.0.0.1:32769 127.0.0.1:5001 timer:(timewait,3.430ms,0) ino:0 sk:cf209620
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2005-08-12 12:59:17 -03:00
|
|
|
/*
|
|
|
|
* tcp_diag.c Module for monitoring TCP transport protocols sockets.
|
|
|
|
*
|
|
|
|
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
2015-12-16 12:30:05 +09:00
|
|
|
#include <linux/net.h>
|
|
|
|
#include <linux/sock_diag.h>
|
[INET_DIAG]: Move the tcp_diag interface to the proper place
With this the previous setup is back, i.e. tcp_diag can be built as a module,
as dccp_diag and both share the infrastructure available in inet_diag.
If one selects CONFIG_INET_DIAG as module CONFIG_INET_TCP_DIAG will also be
built as a module, as will CONFIG_INET_DCCP_DIAG, if CONFIG_IP_DCCP was
selected static or as a module, if CONFIG_INET_DIAG is y, being statically
linked CONFIG_INET_TCP_DIAG will follow suit and CONFIG_INET_DCCP_DIAG will be
built in the same manner as CONFIG_IP_DCCP.
Now to aim at UDP, converting it to use inet_hashinfo, so that we can use
iproute2 for UDP sockets as well.
Ah, just to show an example of this new infrastructure working for DCCP :-)
[root@qemu ~]# ./ss -dane
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 0 *:5001 *:* ino:942 sk:cfd503a0
ESTAB 0 0 127.0.0.1:5001 127.0.0.1:32770 ino:943 sk:cfd50a60
ESTAB 0 0 127.0.0.1:32770 127.0.0.1:5001 ino:947 sk:cfd50700
TIME-WAIT 0 0 127.0.0.1:32769 127.0.0.1:5001 timer:(timewait,3.430ms,0) ino:0 sk:cf209620
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2005-08-12 12:59:17 -03:00
|
|
|
#include <linux/inet_diag.h>
|
|
|
|
|
|
|
|
#include <linux/tcp.h>
|
|
|
|
|
2017-08-31 09:59:39 -07:00
|
|
|
#include <net/netlink.h>
|
[INET_DIAG]: Move the tcp_diag interface to the proper place
With this the previous setup is back, i.e. tcp_diag can be built as a module,
as dccp_diag and both share the infrastructure available in inet_diag.
If one selects CONFIG_INET_DIAG as module CONFIG_INET_TCP_DIAG will also be
built as a module, as will CONFIG_INET_DCCP_DIAG, if CONFIG_IP_DCCP was
selected static or as a module, if CONFIG_INET_DIAG is y, being statically
linked CONFIG_INET_TCP_DIAG will follow suit and CONFIG_INET_DCCP_DIAG will be
built in the same manner as CONFIG_IP_DCCP.
Now to aim at UDP, converting it to use inet_hashinfo, so that we can use
iproute2 for UDP sockets as well.
Ah, just to show an example of this new infrastructure working for DCCP :-)
[root@qemu ~]# ./ss -dane
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 0 *:5001 *:* ino:942 sk:cfd503a0
ESTAB 0 0 127.0.0.1:5001 127.0.0.1:32770 ino:943 sk:cfd50a60
ESTAB 0 0 127.0.0.1:32770 127.0.0.1:5001 ino:947 sk:cfd50700
TIME-WAIT 0 0 127.0.0.1:32769 127.0.0.1:5001 timer:(timewait,3.430ms,0) ino:0 sk:cf209620
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2005-08-12 12:59:17 -03:00
|
|
|
#include <net/tcp.h>
|
|
|
|
|
|
|
|
static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
|
|
|
|
void *_info)
|
|
|
|
{
|
|
|
|
struct tcp_info *info = _info;
|
|
|
|
|
2017-12-20 11:12:52 +08:00
|
|
|
if (inet_sk_state_load(sk) == TCP_LISTEN) {
|
2019-11-05 14:11:53 -08:00
|
|
|
r->idiag_rqueue = READ_ONCE(sk->sk_ack_backlog);
|
2019-11-05 14:11:54 -08:00
|
|
|
r->idiag_wqueue = READ_ONCE(sk->sk_max_ack_backlog);
|
2015-06-15 11:26:20 -04:00
|
|
|
} else if (sk->sk_type == SOCK_STREAM) {
|
|
|
|
const struct tcp_sock *tp = tcp_sk(sk);
|
|
|
|
|
2019-10-10 20:17:40 -07:00
|
|
|
r->idiag_rqueue = max_t(int, READ_ONCE(tp->rcv_nxt) -
|
|
|
|
READ_ONCE(tp->copied_seq), 0);
|
2019-10-10 20:17:41 -07:00
|
|
|
r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una;
|
2007-09-18 13:26:31 -07:00
|
|
|
}
|
2015-04-03 09:17:27 +01:00
|
|
|
if (info)
|
[INET_DIAG]: Move the tcp_diag interface to the proper place
With this the previous setup is back, i.e. tcp_diag can be built as a module,
as dccp_diag and both share the infrastructure available in inet_diag.
If one selects CONFIG_INET_DIAG as module CONFIG_INET_TCP_DIAG will also be
built as a module, as will CONFIG_INET_DCCP_DIAG, if CONFIG_IP_DCCP was
selected static or as a module, if CONFIG_INET_DIAG is y, being statically
linked CONFIG_INET_TCP_DIAG will follow suit and CONFIG_INET_DCCP_DIAG will be
built in the same manner as CONFIG_IP_DCCP.
Now to aim at UDP, converting it to use inet_hashinfo, so that we can use
iproute2 for UDP sockets as well.
Ah, just to show an example of this new infrastructure working for DCCP :-)
[root@qemu ~]# ./ss -dane
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 0 *:5001 *:* ino:942 sk:cfd503a0
ESTAB 0 0 127.0.0.1:5001 127.0.0.1:32770 ino:943 sk:cfd50a60
ESTAB 0 0 127.0.0.1:32770 127.0.0.1:5001 ino:947 sk:cfd50700
TIME-WAIT 0 0 127.0.0.1:32769 127.0.0.1:5001 timer:(timewait,3.430ms,0) ino:0 sk:cf209620
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2005-08-12 12:59:17 -03:00
|
|
|
tcp_get_info(sk, info);
|
|
|
|
}
|
|
|
|
|
2017-08-31 09:59:39 -07:00
|
|
|
#ifdef CONFIG_TCP_MD5SIG
|
|
|
|
static void tcp_diag_md5sig_fill(struct tcp_diag_md5sig *info,
|
|
|
|
const struct tcp_md5sig_key *key)
|
|
|
|
{
|
|
|
|
info->tcpm_family = key->family;
|
|
|
|
info->tcpm_prefixlen = key->prefixlen;
|
|
|
|
info->tcpm_keylen = key->keylen;
|
|
|
|
memcpy(info->tcpm_key, key->key, key->keylen);
|
|
|
|
|
|
|
|
if (key->family == AF_INET)
|
|
|
|
info->tcpm_addr[0] = key->addr.a4.s_addr;
|
|
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
|
|
else if (key->family == AF_INET6)
|
|
|
|
memcpy(&info->tcpm_addr, &key->addr.a6,
|
|
|
|
sizeof(info->tcpm_addr));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static int tcp_diag_put_md5sig(struct sk_buff *skb,
|
|
|
|
const struct tcp_md5sig_info *md5sig)
|
|
|
|
{
|
|
|
|
const struct tcp_md5sig_key *key;
|
|
|
|
struct tcp_diag_md5sig *info;
|
|
|
|
struct nlattr *attr;
|
|
|
|
int md5sig_count = 0;
|
|
|
|
|
|
|
|
hlist_for_each_entry_rcu(key, &md5sig->head, node)
|
|
|
|
md5sig_count++;
|
|
|
|
if (md5sig_count == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
attr = nla_reserve(skb, INET_DIAG_MD5SIG,
|
|
|
|
md5sig_count * sizeof(struct tcp_diag_md5sig));
|
|
|
|
if (!attr)
|
|
|
|
return -EMSGSIZE;
|
|
|
|
|
|
|
|
info = nla_data(attr);
|
|
|
|
memset(info, 0, md5sig_count * sizeof(struct tcp_diag_md5sig));
|
|
|
|
hlist_for_each_entry_rcu(key, &md5sig->head, node) {
|
|
|
|
tcp_diag_md5sig_fill(info++, key);
|
|
|
|
if (--md5sig_count == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-08-30 12:25:48 +02:00
|
|
|
static int tcp_diag_put_ulp(struct sk_buff *skb, struct sock *sk,
|
2025-03-06 12:29:27 +01:00
|
|
|
const struct tcp_ulp_ops *ulp_ops, bool net_admin)
|
2019-08-30 12:25:48 +02:00
|
|
|
{
|
|
|
|
struct nlattr *nest;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
nest = nla_nest_start_noflag(skb, INET_DIAG_ULP_INFO);
|
|
|
|
if (!nest)
|
|
|
|
return -EMSGSIZE;
|
|
|
|
|
|
|
|
err = nla_put_string(skb, INET_ULP_INFO_NAME, ulp_ops->name);
|
|
|
|
if (err)
|
|
|
|
goto nla_failure;
|
|
|
|
|
tcp: ulp: diag: more info without CAP_NET_ADMIN
When introduced in commit 61723b393292 ("tcp: ulp: add functions to dump
ulp-specific information"), the whole ULP diag info has been exported
only if the requester had CAP_NET_ADMIN.
It looks like not everything is sensitive, and some info can be exported
to all users in order to ease the debugging from the userspace side
without requiring additional capabilities. Each layer should then decide
what can be exposed to everybody. The 'net_admin' boolean is then passed
to the different layers.
On kTLS side, it looks like there is nothing sensitive there: version,
cipher type, tx/rx user config type, plus some flags. So, only some
metadata about the configuration, no cryptographic info like keys, etc.
Then, everything can be exported to all users.
On MPTCP side, that's different. The MPTCP-related sequence numbers per
subflow should certainly not be exposed to everybody. For example, the
DSS mapping and ssn_offset would give all users on the system access to
narrow ranges of values for the subflow TCP sequence numbers and
MPTCP-level DSNs, and then ease packet injection. The TCP diag interface
doesn't expose the TCP sequence numbers for TCP sockets, so best to do
the same here. The rest -- token, IDs, flags -- can be exported to
everybody.
Acked-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20250306-net-next-tcp-ulp-diag-net-admin-v1-2-06afdd860fc9@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-03-06 12:29:28 +01:00
|
|
|
if (ulp_ops->get_info)
|
|
|
|
err = ulp_ops->get_info(sk, skb, net_admin);
|
2019-08-30 12:25:48 +02:00
|
|
|
if (err)
|
|
|
|
goto nla_failure;
|
|
|
|
|
|
|
|
nla_nest_end(skb, nest);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
nla_failure:
|
|
|
|
nla_nest_cancel(skb, nest);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2017-08-31 09:59:39 -07:00
|
|
|
static int tcp_diag_get_aux(struct sock *sk, bool net_admin,
|
|
|
|
struct sk_buff *skb)
|
|
|
|
{
|
2019-08-30 12:25:48 +02:00
|
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
2025-03-06 12:29:27 +01:00
|
|
|
const struct tcp_ulp_ops *ulp_ops;
|
2019-08-30 12:25:48 +02:00
|
|
|
int err = 0;
|
|
|
|
|
2017-08-31 09:59:39 -07:00
|
|
|
#ifdef CONFIG_TCP_MD5SIG
|
|
|
|
if (net_admin) {
|
|
|
|
struct tcp_md5sig_info *md5sig;
|
|
|
|
|
|
|
|
rcu_read_lock();
|
|
|
|
md5sig = rcu_dereference(tcp_sk(sk)->md5sig_info);
|
|
|
|
if (md5sig)
|
|
|
|
err = tcp_diag_put_md5sig(skb, md5sig);
|
|
|
|
rcu_read_unlock();
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2025-03-06 12:29:27 +01:00
|
|
|
ulp_ops = icsk->icsk_ulp_ops;
|
|
|
|
if (ulp_ops) {
|
|
|
|
err = tcp_diag_put_ulp(skb, sk, ulp_ops, net_admin);
|
|
|
|
if (err < 0)
|
2019-08-30 12:25:48 +02:00
|
|
|
return err;
|
|
|
|
}
|
2025-03-06 12:29:27 +01:00
|
|
|
|
2017-08-31 09:59:39 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t tcp_diag_get_aux_size(struct sock *sk, bool net_admin)
|
|
|
|
{
|
2019-08-30 12:25:48 +02:00
|
|
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
2017-08-31 09:59:39 -07:00
|
|
|
size_t size = 0;
|
|
|
|
|
|
|
|
#ifdef CONFIG_TCP_MD5SIG
|
|
|
|
if (net_admin && sk_fullsock(sk)) {
|
|
|
|
const struct tcp_md5sig_info *md5sig;
|
|
|
|
const struct tcp_md5sig_key *key;
|
|
|
|
size_t md5sig_count = 0;
|
|
|
|
|
|
|
|
rcu_read_lock();
|
|
|
|
md5sig = rcu_dereference(tcp_sk(sk)->md5sig_info);
|
|
|
|
if (md5sig) {
|
|
|
|
hlist_for_each_entry_rcu(key, &md5sig->head, node)
|
|
|
|
md5sig_count++;
|
|
|
|
}
|
|
|
|
rcu_read_unlock();
|
|
|
|
size += nla_total_size(md5sig_count *
|
|
|
|
sizeof(struct tcp_diag_md5sig));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2025-03-06 12:29:27 +01:00
|
|
|
if (sk_fullsock(sk)) {
|
2019-08-30 12:25:48 +02:00
|
|
|
const struct tcp_ulp_ops *ulp_ops;
|
|
|
|
|
|
|
|
ulp_ops = icsk->icsk_ulp_ops;
|
|
|
|
if (ulp_ops) {
|
|
|
|
size += nla_total_size(0) +
|
|
|
|
nla_total_size(TCP_ULP_NAME_MAX);
|
tcp: ulp: diag: more info without CAP_NET_ADMIN
When introduced in commit 61723b393292 ("tcp: ulp: add functions to dump
ulp-specific information"), the whole ULP diag info has been exported
only if the requester had CAP_NET_ADMIN.
It looks like not everything is sensitive, and some info can be exported
to all users in order to ease the debugging from the userspace side
without requiring additional capabilities. Each layer should then decide
what can be exposed to everybody. The 'net_admin' boolean is then passed
to the different layers.
On kTLS side, it looks like there is nothing sensitive there: version,
cipher type, tx/rx user config type, plus some flags. So, only some
metadata about the configuration, no cryptographic info like keys, etc.
Then, everything can be exported to all users.
On MPTCP side, that's different. The MPTCP-related sequence numbers per
subflow should certainly not be exposed to everybody. For example, the
DSS mapping and ssn_offset would give all users on the system access to
narrow ranges of values for the subflow TCP sequence numbers and
MPTCP-level DSNs, and then ease packet injection. The TCP diag interface
doesn't expose the TCP sequence numbers for TCP sockets, so best to do
the same here. The rest -- token, IDs, flags -- can be exported to
everybody.
Acked-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20250306-net-next-tcp-ulp-diag-net-admin-v1-2-06afdd860fc9@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-03-06 12:29:28 +01:00
|
|
|
if (ulp_ops->get_info_size)
|
|
|
|
size += ulp_ops->get_info_size(sk, net_admin);
|
2019-08-30 12:25:48 +02:00
|
|
|
}
|
|
|
|
}
|
2017-08-31 09:59:39 -07:00
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2011-12-09 06:23:18 +00:00
|
|
|
static void tcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
2020-02-25 15:04:15 -08:00
|
|
|
const struct inet_diag_req_v2 *r)
|
2011-12-09 06:23:18 +00:00
|
|
|
{
|
2022-09-07 18:10:20 -07:00
|
|
|
struct inet_hashinfo *hinfo;
|
|
|
|
|
|
|
|
hinfo = sock_net(cb->skb->sk)->ipv4.tcp_death_row.hashinfo;
|
|
|
|
|
|
|
|
inet_diag_dump_icsk(hinfo, skb, cb, r);
|
2011-12-09 06:23:18 +00:00
|
|
|
}
|
|
|
|
|
2020-02-25 15:04:09 -08:00
|
|
|
static int tcp_diag_dump_one(struct netlink_callback *cb,
|
2015-03-10 07:15:54 -07:00
|
|
|
const struct inet_diag_req_v2 *req)
|
2011-12-09 06:23:18 +00:00
|
|
|
{
|
2022-09-07 18:10:20 -07:00
|
|
|
struct inet_hashinfo *hinfo;
|
|
|
|
|
|
|
|
hinfo = sock_net(cb->skb->sk)->ipv4.tcp_death_row.hashinfo;
|
|
|
|
|
|
|
|
return inet_diag_dump_one_icsk(hinfo, cb, req);
|
2011-12-09 06:23:18 +00:00
|
|
|
}
|
|
|
|
|
2015-12-16 12:30:05 +09:00
|
|
|
#ifdef CONFIG_INET_DIAG_DESTROY
|
|
|
|
static int tcp_diag_destroy(struct sk_buff *in_skb,
|
|
|
|
const struct inet_diag_req_v2 *req)
|
|
|
|
{
|
|
|
|
struct net *net = sock_net(in_skb->sk);
|
2022-09-07 18:10:20 -07:00
|
|
|
struct inet_hashinfo *hinfo;
|
|
|
|
struct sock *sk;
|
2016-08-23 21:05:27 -07:00
|
|
|
int err;
|
2015-12-16 12:30:05 +09:00
|
|
|
|
2022-09-07 18:10:20 -07:00
|
|
|
hinfo = net->ipv4.tcp_death_row.hashinfo;
|
|
|
|
sk = inet_diag_find_one_icsk(net, hinfo, req);
|
|
|
|
|
2015-12-16 12:30:05 +09:00
|
|
|
if (IS_ERR(sk))
|
|
|
|
return PTR_ERR(sk);
|
|
|
|
|
2016-08-23 21:05:27 -07:00
|
|
|
err = sock_diag_destroy(sk, ECONNABORTED);
|
|
|
|
|
|
|
|
sock_gen_put(sk);
|
|
|
|
|
|
|
|
return err;
|
2015-12-16 12:30:05 +09:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-11-19 15:43:27 -08:00
|
|
|
static const struct inet_diag_handler tcp_diag_handler = {
|
2024-01-22 11:25:57 +00:00
|
|
|
.owner = THIS_MODULE,
|
2017-08-31 09:59:39 -07:00
|
|
|
.dump = tcp_diag_dump,
|
|
|
|
.dump_one = tcp_diag_dump_one,
|
|
|
|
.idiag_get_info = tcp_diag_get_info,
|
|
|
|
.idiag_get_aux = tcp_diag_get_aux,
|
|
|
|
.idiag_get_aux_size = tcp_diag_get_aux_size,
|
|
|
|
.idiag_type = IPPROTO_TCP,
|
|
|
|
.idiag_info_size = sizeof(struct tcp_info),
|
2015-12-16 12:30:05 +09:00
|
|
|
#ifdef CONFIG_INET_DIAG_DESTROY
|
2017-08-31 09:59:39 -07:00
|
|
|
.destroy = tcp_diag_destroy,
|
2015-12-16 12:30:05 +09:00
|
|
|
#endif
|
[INET_DIAG]: Move the tcp_diag interface to the proper place
With this the previous setup is back, i.e. tcp_diag can be built as a module,
as dccp_diag and both share the infrastructure available in inet_diag.
If one selects CONFIG_INET_DIAG as module CONFIG_INET_TCP_DIAG will also be
built as a module, as will CONFIG_INET_DCCP_DIAG, if CONFIG_IP_DCCP was
selected static or as a module, if CONFIG_INET_DIAG is y, being statically
linked CONFIG_INET_TCP_DIAG will follow suit and CONFIG_INET_DCCP_DIAG will be
built in the same manner as CONFIG_IP_DCCP.
Now to aim at UDP, converting it to use inet_hashinfo, so that we can use
iproute2 for UDP sockets as well.
Ah, just to show an example of this new infrastructure working for DCCP :-)
[root@qemu ~]# ./ss -dane
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 0 *:5001 *:* ino:942 sk:cfd503a0
ESTAB 0 0 127.0.0.1:5001 127.0.0.1:32770 ino:943 sk:cfd50a60
ESTAB 0 0 127.0.0.1:32770 127.0.0.1:5001 ino:947 sk:cfd50700
TIME-WAIT 0 0 127.0.0.1:32769 127.0.0.1:5001 timer:(timewait,3.430ms,0) ino:0 sk:cf209620
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2005-08-12 12:59:17 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
static int __init tcp_diag_init(void)
|
|
|
|
{
|
|
|
|
return inet_diag_register(&tcp_diag_handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void __exit tcp_diag_exit(void)
|
|
|
|
{
|
|
|
|
inet_diag_unregister(&tcp_diag_handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
module_init(tcp_diag_init);
|
|
|
|
module_exit(tcp_diag_exit);
|
|
|
|
MODULE_LICENSE("GPL");
|
2023-11-18 19:30:06 -08:00
|
|
|
MODULE_DESCRIPTION("TCP socket monitoring via SOCK_DIAG");
|
2011-12-15 02:43:27 +00:00
|
|
|
MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 2-6 /* AF_INET - IPPROTO_TCP */);
|