Allow ssfilter_bytecompile to return 0 for filter ops the kernel
does not support. If such an op is in the filter string then all
filtering is done in userspace.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Extract parsing of sockstat and filter from inet_show_sock.
While moving run_ssfilter into callers of inet_show_sock enable
userspace filtering before the kill.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
SK_MEMINFO_DROPS is added in linux-4.7 for TCP, UDP and SCTP
skmem will display the socket drop count using d prefix as in :
$ ss -tm src :22 | more
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 52 10.246.7.151:ssh 172.20.10.101:50759
skmem:(r0,rb8388608,t0,tb8388608,f1792,w2304,o0,bl0,d0)
Signed-off-by: Eric Dumazet <edumazet@google.com>
Kernel sets info->tcpi_min_rtt to ~0U when no RTT sample was ever
taken for the session, thus min_rtt is unknown.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Passing a filter expression and selecting an address family using the
'-f' flag would overwrite the state filter by accident. Therefore
calling e.g. 'ss -nl -f inet '(sport = :22)' would not only print
listening sockets (as requested by '-l' flag) but connected ones, as
well.
Fix this by reusing the formerly ineffective call to filter_states_set()
to restore the state filter as it was before the call to
filter_af_set().
Signed-off-by: Phil Sutter <phil@nwl.cc>
There are only three users which require it to be reentrant, the rest is
fine without. Instead, provide a reentrant format_host_r() for users
which need it.
Signed-off-by: Phil Sutter <phil@nwl.cc>
This patch adds a -K / --kill option to ss that attempts to
forcibly close matching sockets using SOCK_DESTROY.
Because ss typically prints sockets instead of acting on them,
and because the kernel only supports forcibly closing some types
of sockets, the output of -K is as follows:
- If closing the socket succeeds, the socket is printed.
- If the kernel does not support forcibly closing this type of
socket (e.g., if it's a UDP socket, or a TIME_WAIT socket),
the socket is silently skipped.
- If an error occurs (e.g., permission denied), the error is
reported and ss exits.
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
fgets() will read at most size-1 bytes into the buffer and add a
terminating null-char at the end. Therefore it is not necessary to pass
a reduced buffer size when calling it.
This change was generated using the following semantic patch:
@@
identifier buf, fp;
@@
- fgets(buf, sizeof(buf) - 1, fp)
+ fgets(buf, sizeof(buf), fp)
Signed-off-by: Phil Sutter <phil@nwl.cc>
Although not fundamentally necessary to check return codes in these
spots, preventing the warnings will put new ones into focus.
Signed-off-by: Phil Sutter <phil@nwl.cc>
No need to keep static port boundaries global, they are not used
directly. Keeping them local also allows to safely reduce their names to
the minimum. Assign hardcoded fallback values also if fscanf() fails.
Get rid of unnecessary braces around return parameter.
Instead of more or less duplicating is_ephemeral() in run_ssfilter(),
simply call the function instead.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Exit early or continue on error instead of putting conditional into
conditional to make reading the code a bit easier.
Also, the call to memcpy() can be skipped by initialising prog with the
desired prefix.
Signed-off-by: Phil Sutter <phil@nwl.cc>
When getopt_long encounters an option which has not been registered, it
returns '?'. React upon that and call usage() instead of help() so ss
returns with a non-zero exit status.
Signed-off-by: Phil Sutter <phil@nwl.cc>
I've updated Jose's patch to make it slightly simpler (eg: calloc instead
of malloc+memset), and ported it to 4.2.0 which requires it as well, and
attached it to this e-mail.
I can confirm that with this patch 4.1.1 doesn't segfault on me anymore.
The commit message should be reworked I guess though everything's in it
and I didn't want to modify his description.
Can it be merged as-is or should I reword the commit message and reference
Jose as the fix reporter ? We should not let this bug live forever.
From: "j.ps@openmailbox.org" <j.ps@openmailbox.org>
Essentially all that is needed to get rid of this issue is the
addition of:
memset(u, 0, sizeof(*u));
after:
if (!(u = malloc(sizeof(*u))))
break;
Also patched some other situations (strcpy and sprintf uses) that
potentially produce the same results.
Signed-off-by: Jose P Santos <j.ps@openmailbox.org>
[ wt: made Jose's patch slightly simpler, all credits to him for the diag ]
Signed-off-by: Willy Tarreau <w@1wt.eu>
Commit 1527a17 introduced a change where the second of two ssfilter_parse()
calls in ss.c was moved outside of a conditional block (ss.c: ~3575). This
commit enabled the parsing of services, such as 'sport = :ssh', but
inadvertently broke the '-F' file-based filtering:
Hi:
I found a formatting bug in the 4.1.1 ss command. The following line was
incorrectly output due to passing a negative length to printf() when
displaying the local address. In this instance hostapd does a "bind to
device" on cdreth0 and then does a udp "in address any" port 67 bind.
Please note the whitespace between the '*' and ' %cdreth0:67'
'udp UNCONN 0 0 ** %cdreth0:67* *:* users:(("hostapd",pid=19241,fd=5))'
Attached is my patch for the bug fix, it might be prudent to add more
guard code looking for negative length format codes.
Sincerely, Mike
This was working before, but only if realloc a) succeeded and b) did not
move the buffer to a different location. ''**buf = **new_buf' then
writes the value of *new_buf's first field into that of *buf.
Signed-off-by: Phil Sutter <phil@nwl.cc>
It really partially reverts:
ec4d0d8a9d (ss: Replace unixstat struct by new sockstat struct)
but adds few fields (name & peer_name) from removed unixstat to sockstat struct to easy
return original code.
Fixes: ec4d0d8a9d (ss: Replace unixstat struct by new sockstat struct)
Reported-by: Marc Dietrich <marvin24@gmx.de>
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
After commit 8250bc9ff4 ("ss: Unify inet sockets output") raw sockets
are displayed as udp because dgram_show_line() is used for both and
thus IPPROTO_UDP is used for both so proto_name() returns "udp".
Fix this by checking dg_proto which is set according to the caller of
dgram_show_line().
Reported-by: Miha Marolt <miham@beyondsemi.com>
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
If available and set, print 'v6only:1' for AF_INET6 sockets upon request
of extended information. For IPv6 sockets bound to in6addr_any, this is
the only way to determine if they will also accept IPv4 requests or not.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Use the IPv4/IPv6/TCP/UDP multicast groups of NETLINK_SOCK_DIAG
to filter and display socket statistics as they are destroyed.
Kernel support patch series: 24029a3603cfa633e8bc2b3fb3e48e76c497831d
Signed-off-by: Craig Gallek <kraig@google.com>
s->local.data is a pointer to a field of a non-NULL struct, and hence
cannot be NULL, thus comparing it to 0 is always false, and thus the
return is always false.
Presumably this was meant to be a check whether s->local.data[0] (which
I believe stores af_packet protocol) is 0, ie. ANY.
Change-Id: Ia232f5b06ce081e3b2fb6338f1a709cd94e03ae5
Fixes:
ss.c:1018:37: error: comparison of array 's->local.data' equal to a null pointer is always false [-Werror,-Wtautological-pointer-compare]
return s->lport == 0 && s->local.data == 0;
~~~~~~~~~^~~~ ~
1 error generated.
ss currently dumps IPv4 sockets, then IPv6 sockets from the kernel,
even if -4 or -6 option was given. Filtering in user space then has to
drop all sockets of wrong family. Such a waste of time...
Before :
$ time ss -tn -4 | wc -l
251659
real 0m1.241s
user 0m0.423s
sys 0m0.806s
After:
$ time ss -tn -4 | wc -l
251672
real 0m0.779s
user 0m0.412s
sys 0m0.386s
Signed-off-by: Eric Dumazet <edumazet@google.com>
Lets implement a full cache with proper hash table, memory got cheaper
these days.
Before :
$ time ss -t | wc -l
529678
real 0m22.708s
user 0m19.591s
sys 0m2.969s
After :
$ time ss -t | wc -l
528291
real 0m5.078s
user 0m4.099s
sys 0m0.985s
Signed-off-by: Eric Dumazet <edumazet@google.com>
On Fri, 2015-05-29 at 13:30 +0300, Vadim Kochan wrote:
> From: Vadim Kochan <vadim4j@gmail.com>
>
> Use strdup instead of malloc, and get rid of bad strcpy.
>
> Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
> ---
> misc/ss.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/misc/ss.c b/misc/ss.c
> index 347e3a1..a719466 100644
> --- a/misc/ss.c
> +++ b/misc/ss.c
> @@ -1908,8 +1908,7 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
>
> if (tb[INET_DIAG_CONG]) {
> const char *cong_attr = rta_getattr_str(tb[INET_DIAG_CONG]);
> - s.cong_alg = malloc(strlen(cong_attr + 1));
> - strcpy(s.cong_alg, cong_attr);
> + s.cong_alg = strdup(cong_attr);
> }
>
> if (TCPI_HAS_OPT(info, TCPI_OPT_WSCALE)) {
I doubt TCP_CA_NAME_MAX will ever change in the kernel : 16 bytes.
Its typically "cubic" and less than 8 bytes.
Using 8 bytes to point to a malloc(8) is a waste.
Please remove the memory allocation, or store the pointer, since
tcp_show_info() does the malloc()/free() before return.
Missing space before dctcp: markers.
With dctcp, cwnd=2 is pretty common, just display cwnd value even
if cwnd has this value, it makes parsing easier.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Kernel can give us smaller tcp_info than our.
We copy the kernel provided structure and fill with 0
the remaining part.
Lets clear only the missing part to save some cycles, as we intend to
slightly increase tcp_info size in the future.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Fixed applying family & socket type filters.
It was not possible to select UDP & UNIX sockets together.
Now selected families are ORed.
The problem was that filters were combined by AND.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Reported-By: Mihai Moldovan <ionic@ionic.de>