From 116bb40f314cacf369ccddaee494af4a5f6b7ab4 Mon Sep 17 00:00:00 2001 From: Joe Yin <38340644+kernel-z@users.noreply.github.com> Date: Mon, 18 Jun 2018 23:34:52 +0800 Subject: [PATCH] Patch for tools/tcpaccept.py (#1834) fix socket protocol reading --- tools/tcpaccept.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tools/tcpaccept.py b/tools/tcpaccept.py index 52aefdf1406c..8f33c8f893c2 100755 --- a/tools/tcpaccept.py +++ b/tools/tcpaccept.py @@ -82,7 +82,37 @@ // check this is TCP u8 protocol = 0; // workaround for reading the sk_protocol bitfield: - bpf_probe_read(&protocol, 1, (void *)((long)&newsk->sk_wmem_queued) - 3); + + // Following comments add by Joe Yin: + // Unfortunately,it can not work since Linux 4.10, + // because the sk_wmem_queued is not following the bitfield of sk_protocol. + // And the following member is sk_gso_max_segs. + // So, we can use this: + // bpf_probe_read(&protocol, 1, (void *)((u64)&newsk->sk_gso_max_segs) - 3); + // In order to diff the pre-4.10 and 4.10+ ,introduce the variables gso_max_segs_offset,sk_lingertime, + // sk_lingertime is closed to the gso_max_segs_offset,and + // the offset between the two members is 4 + + int gso_max_segs_offset = offsetof(struct sock, sk_gso_max_segs); + int sk_lingertime_offset = offsetof(struct sock, sk_lingertime); + + if (sk_lingertime_offset - gso_max_segs_offset == 4) + // 4.10+ with little endian +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + bpf_probe_read(&protocol, 1, (void *)((u64)&newsk->sk_gso_max_segs) - 3); + else + // pre-4.10 with little endian + bpf_probe_read(&protocol, 1, (void *)((u64)&newsk->sk_wmem_queued) - 3); +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + // 4.10+ with big endian + bpf_probe_read(&protocol, 1, (void *)((u64)&newsk->sk_gso_max_segs) - 1); + else + // pre-4.10 with big endian + bpf_probe_read(&protocol, 1, (void *)((u64)&newsk->sk_wmem_queued) - 1); +#else +# error "Fix your compiler's __BYTE_ORDER__?!" +#endif + if (protocol != IPPROTO_TCP) return 0;