summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@strace.io>2022-11-26 08:00:00 +0000
committerDmitry V. Levin <ldv@strace.io>2022-11-26 08:00:00 +0000
commit238f5799fe1d87147e851f3fd099186185e39e3f (patch)
tree25d6c83f9904ac17db61ab6499303b2d9f11a291
parent3e9ef7a242267bc8921dbaafcea5bbec89bdc059 (diff)
downloadstrace-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.c33
-rw-r--r--src/xlat/icmp_filter_flags.in14
-rw-r--r--src/xlat/icmpfilterflags.in13
-rw-r--r--tests/net-icmp_filter.c66
4 files changed, 83 insertions, 43 deletions
diff --git a/src/net.c b/src/net.c
index 8506d0248..bb8a44725 100644
--- a/src/net.c
+++ b/src/net.c
@@ -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;