diff options
author | Dmitry V. Levin <ldv@strace.io> | 2022-11-26 08:00:00 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@strace.io> | 2022-11-26 08:00:00 +0000 |
commit | 238f5799fe1d87147e851f3fd099186185e39e3f (patch) | |
tree | 25d6c83f9904ac17db61ab6499303b2d9f11a291 | |
parent | 3e9ef7a242267bc8921dbaafcea5bbec89bdc059 (diff) | |
download | strace-238f5799fe1d87147e851f3fd099186185e39e3f.tar.gz |
print_icmp_filter: print icmp_filter as a bitset
* src/xlat/icmp_filter_flags.in: New file.
* src/xlat/icmpfilterflags.in: Remove.
* src/net.c: Include "xlat/icmp_filter_flags.h" instead of
"xlat/icmpfilterflags.h".
(print_icmp_filter): Print struct icmp_filter.data as a bitset.
* tests/net-icmp_filter.c (main): Update expected output.
-rw-r--r-- | src/net.c | 33 | ||||
-rw-r--r-- | src/xlat/icmp_filter_flags.in | 14 | ||||
-rw-r--r-- | src/xlat/icmpfilterflags.in | 13 | ||||
-rw-r--r-- | tests/net-icmp_filter.c | 66 |
4 files changed, 83 insertions, 43 deletions
@@ -758,7 +758,7 @@ print_tpacket_stats(struct tcb *const tcp, const kernel_ulong_t addr, tprint_struct_end(); } -#include "xlat/icmpfilterflags.h" +#include "xlat/icmp_filter_flags.h" static void print_icmp_filter(struct tcb *const tcp, const kernel_ulong_t addr, int len) @@ -775,9 +775,34 @@ print_icmp_filter(struct tcb *const tcp, const kernel_ulong_t addr, int len) if (umoven_or_printaddr(tcp, addr, len, &filter)) return; - tprints("~("); - printflags(icmpfilterflags, ~filter.data, "ICMP_???"); - tprints(")"); + uint32_t data = filter.data; + static_assert(sizeof(filter.data) == sizeof(data), + "struct icmp_filter.data is not 32-bit long"); + + uint32_t inverted_data; + uint32_t *p = &data; + + /* check whether more than half of the bits are set */ + if (popcount32(p, 1) > sizeof(*p) * 8 / 2) { + /* show those bits that are NOT in the set */ + inverted_data = ~data; + p = &inverted_data; + tprints("~"); + } + + tprint_bitset_begin(); + bool next = false; + for (int i = 0;; ++i) { + i = next_set_bit(p, i, sizeof(*p) * 8); + if (i < 0) + break; + if (next) + tprint_bitset_next(); + else + next = true; + printxval(icmp_filter_flags, i, "ICMP_???"); + } + tprint_bitset_end(); } static void diff --git a/src/xlat/icmp_filter_flags.in b/src/xlat/icmp_filter_flags.in new file mode 100644 index 000000000..75f75772a --- /dev/null +++ b/src/xlat/icmp_filter_flags.in @@ -0,0 +1,14 @@ +#value_indexed +ICMP_ECHOREPLY 0 +ICMP_DEST_UNREACH 3 +ICMP_SOURCE_QUENCH 4 +ICMP_REDIRECT 5 +ICMP_ECHO 8 +ICMP_TIME_EXCEEDED 11 +ICMP_PARAMETERPROB 12 +ICMP_TIMESTAMP 13 +ICMP_TIMESTAMPREPLY 14 +ICMP_INFO_REQUEST 15 +ICMP_INFO_REPLY 16 +ICMP_ADDRESS 17 +ICMP_ADDRESSREPLY 18 diff --git a/src/xlat/icmpfilterflags.in b/src/xlat/icmpfilterflags.in deleted file mode 100644 index dac579edb..000000000 --- a/src/xlat/icmpfilterflags.in +++ /dev/null @@ -1,13 +0,0 @@ -1<<ICMP_ECHOREPLY -1<<ICMP_DEST_UNREACH -1<<ICMP_SOURCE_QUENCH -1<<ICMP_REDIRECT -1<<ICMP_ECHO -1<<ICMP_TIME_EXCEEDED -1<<ICMP_PARAMETERPROB -1<<ICMP_TIMESTAMP -1<<ICMP_TIMESTAMPREPLY -1<<ICMP_INFO_REQUEST -1<<ICMP_INFO_REPLY -1<<ICMP_ADDRESS -1<<ICMP_ADDRESSREPLY diff --git a/tests/net-icmp_filter.c b/tests/net-icmp_filter.c index ac316eff2..d644effc2 100644 --- a/tests/net-icmp_filter.c +++ b/tests/net-icmp_filter.c @@ -17,48 +17,62 @@ int main(void) { getsockopt(-1, SOL_RAW, ICMP_FILTER, 0, 0); - printf("getsockopt(-1, SOL_RAW, ICMP_FILTER, NULL, NULL) = -1 %s (%m)\n", - errno2name()); + printf("getsockopt(-1, SOL_RAW, ICMP_FILTER, NULL, NULL) = %s\n", + sprintrc(-1)); setsockopt(-1, SOL_RAW, ICMP_FILTER, NULL, 0); - printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, NULL, 0) = -1 %s (%m)\n", - errno2name()); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, NULL, 0) = %s\n", + sprintrc(-1)); TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, plen); void *const efault = plen + 1; TAIL_ALLOC_OBJECT_CONST_PTR(struct icmp_filter, f); getsockopt(-1, SOL_RAW, ICMP_FILTER, f, plen); - printf("getsockopt(-1, SOL_RAW, ICMP_FILTER, %p, [%d]) = -1 %s (%m)\n", - f, *plen, errno2name()); + printf("getsockopt(-1, SOL_RAW, ICMP_FILTER, %p, [%d]) = %s\n", + f, *plen, sprintrc(-1)); setsockopt(-1, SOL_RAW, ICMP_FILTER, efault, sizeof(*f)); - printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %p, %u) = -1 %s (%m)\n", - efault, (unsigned) sizeof(*f), errno2name()); - - f->data = ~( - 1<<ICMP_ECHOREPLY | - 1<<ICMP_DEST_UNREACH | - 1<<ICMP_SOURCE_QUENCH | - 1<<ICMP_REDIRECT | - 1<<ICMP_TIME_EXCEEDED | - 1<<ICMP_PARAMETERPROB); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %p, %u) = %s\n", + efault, (unsigned) sizeof(*f), sprintrc(-1)); setsockopt(-1, SOL_RAW, ICMP_FILTER, f, -2); - printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %p, -2) = -1 %s (%m)\n", - f, errno2name()); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %p, -2) = %s\n", + f, sprintrc(-1)); + + setsockopt(-1, SOL_RAW, ICMP_FILTER, f, sizeof(*f)); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, ~[], %u) = %s\n", + (unsigned) sizeof(*f), sprintrc(-1)); + + f->data = 0; setsockopt(-1, SOL_RAW, ICMP_FILTER, f, sizeof(*f)); - printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %s, %u) = -1 %s (%m)\n", - "~(1<<ICMP_ECHOREPLY|1<<ICMP_DEST_UNREACH|1<<ICMP_SOURCE_QUENCH" - "|1<<ICMP_REDIRECT|1<<ICMP_TIME_EXCEEDED|1<<ICMP_PARAMETERPROB)", - (unsigned) sizeof(*f), errno2name()); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, [], %u) = %s\n", + (unsigned) sizeof(*f), sprintrc(-1)); + + f->data = 1<<ICMP_ECHOREPLY | + 1<<ICMP_DEST_UNREACH | + 1<<ICMP_SOURCE_QUENCH | + 1<<ICMP_REDIRECT | + 1<<ICMP_TIME_EXCEEDED | + 1<<ICMP_PARAMETERPROB; + static const char data_str[] = + "[ICMP_ECHOREPLY" + " ICMP_DEST_UNREACH" + " ICMP_SOURCE_QUENCH" + " ICMP_REDIRECT" + " ICMP_TIME_EXCEEDED" + " ICMP_PARAMETERPROB]"; + + setsockopt(-1, SOL_RAW, ICMP_FILTER, f, sizeof(*f)); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %s, %u) = %s\n", + data_str, (unsigned) sizeof(*f), sprintrc(-1)); + + f->data = ~f->data; setsockopt(-1, SOL_RAW, ICMP_FILTER, f, sizeof(*f) * 2); - printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, %s, %u) = -1 %s (%m)\n", - "~(1<<ICMP_ECHOREPLY|1<<ICMP_DEST_UNREACH|1<<ICMP_SOURCE_QUENCH" - "|1<<ICMP_REDIRECT|1<<ICMP_TIME_EXCEEDED|1<<ICMP_PARAMETERPROB)", - (unsigned) sizeof(*f) * 2, errno2name()); + printf("setsockopt(-1, SOL_RAW, ICMP_FILTER, ~%s, %u) = %s\n", + data_str, (unsigned) sizeof(*f) * 2, sprintrc(-1)); puts("+++ exited with 0 +++"); return 0; |