From 5c051a1a11d6d3908034b32cc24ad7e0a84bb6ae Mon Sep 17 00:00:00 2001 From: Ardika Rommy Sanjaya Date: Sat, 7 Jan 2023 10:52:33 +0700 Subject: [PATCH 1/6] Improve mac address --- .../java/pcap/codec/ethernet/Ethernet.java | 4 +- .../main/java/pcap/common/net/MacAddress.java | 17 +- .../java/pcap/tests/BytesToHexBenchmark.java | 139 +++++++++++++++ .../java/pcap/tests/HexToBytesBenchmark.java | 161 ++++++++++++++++++ 4 files changed, 312 insertions(+), 9 deletions(-) create mode 100644 tests/src/test/java/pcap/tests/BytesToHexBenchmark.java create mode 100644 tests/src/test/java/pcap/tests/HexToBytesBenchmark.java diff --git a/codec/src/main/java/pcap/codec/ethernet/Ethernet.java b/codec/src/main/java/pcap/codec/ethernet/Ethernet.java index 419ce021..60c41b81 100644 --- a/codec/src/main/java/pcap/codec/ethernet/Ethernet.java +++ b/codec/src/main/java/pcap/codec/ethernet/Ethernet.java @@ -53,7 +53,7 @@ public static Ethernet newInstance(int size, PacketBuffer buffer) { * @since 1.0.0 */ public MacAddress destination() { - return MacAddress.valueOf((superBuffer.getLong(destinationOffset) >> 16) & 0xffffffffffffL); + return MacAddress.fromLong((superBuffer.getLong(destinationOffset) >> 16) & 0xffffffffffffL); } /** @@ -75,7 +75,7 @@ public Ethernet destination(MacAddress macAddress) { * @since 1.0.0 */ public MacAddress source() { - return MacAddress.valueOf((superBuffer.getLong(sourceOffset) >> 16) & 0xffffffffffffL); + return MacAddress.fromLong((superBuffer.getLong(sourceOffset) >> 16) & 0xffffffffffffL); } /** diff --git a/common/src/main/java/pcap/common/net/MacAddress.java b/common/src/main/java/pcap/common/net/MacAddress.java index b9399d35..f05e7a4c 100644 --- a/common/src/main/java/pcap/common/net/MacAddress.java +++ b/common/src/main/java/pcap/common/net/MacAddress.java @@ -23,19 +23,19 @@ public final class MacAddress implements Serializable { private static final Pattern REGEX = Pattern.compile("[:-]"); /** Zero MAC Address (00:00:00:00:00:00). */ - public static final MacAddress ZERO = valueOf("00:00:00:00:00:00"); + public static final MacAddress ZERO = fromString("00:00:00:00:00:00"); /** Dummy MAC Address (de:ad:be:ef:c0:fe). */ - public static final MacAddress DUMMY = valueOf("de:ad:be:ef:c0:fe"); + public static final MacAddress DUMMY = fromString("de:ad:be:ef:c0:fe"); /** Broadcast MAC Address (ff:ff:ff:ff:ff:ff). */ - public static final MacAddress BROADCAST = valueOf("ff:ff:ff:ff:ff:ff"); + public static final MacAddress BROADCAST = fromString("ff:ff:ff:ff:ff:ff"); /** Multicast Address. */ - public static final MacAddress IPV4_MULTICAST = valueOf("01:00:5e:00:00:00"); + public static final MacAddress IPV4_MULTICAST = fromString("01:00:5e:00:00:00"); /** Multicast mask. */ - public static final MacAddress IPV4_MULTICAST_MASK = valueOf("ff:ff:ff:80:00:00"); + public static final MacAddress IPV4_MULTICAST_MASK = fromString("ff:ff:ff:80:00:00"); private final byte[] address; @@ -99,7 +99,7 @@ public static MacAddress fromString(String stringAddress) { bytes[offset] = (byte) ((hi << 4) + lo); offset += 1; } - return valueOf(bytes); + return fromBytes(bytes); } /** @@ -109,6 +109,7 @@ public static MacAddress fromString(String stringAddress) { * @return an Mac address object. * @since 1.0.0 */ + @Deprecated public static MacAddress valueOf(String stringAddress) { Validate.notIllegalArgument( !Strings.blank(stringAddress), "Address must be not empty or blank."); @@ -130,6 +131,7 @@ public static MacAddress valueOf(String stringAddress) { * @return an Mac address object. * @since 1.0.0 */ + @Deprecated public static MacAddress valueOf(final byte[] bytesAddress) { return fromBytes(bytesAddress); } @@ -152,6 +154,7 @@ public static MacAddress fromBytes(final byte[] bytes) { * @return an Mac address object. * @since 1.0.0 */ + @Deprecated public static MacAddress valueOf(final long longAddress) { return fromLong(longAddress); } @@ -175,7 +178,7 @@ public static MacAddress fromLong(final long longAddress) { (byte) (longAddress >> 8 & 0xff), (byte) (longAddress & 0xff) }; - return valueOf(bytes); + return fromBytes(bytes); } /** diff --git a/tests/src/test/java/pcap/tests/BytesToHexBenchmark.java b/tests/src/test/java/pcap/tests/BytesToHexBenchmark.java new file mode 100644 index 00000000..5c56d3c4 --- /dev/null +++ b/tests/src/test/java/pcap/tests/BytesToHexBenchmark.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2020-2023 Pcap Project + * SPDX-License-Identifier: MIT OR Apache-2.0 + */ +package pcap.tests; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import pcap.common.util.Hexs; +import pcap.common.util.Strings; + +import java.util.Random; + +public class BytesToHexBenchmark { + + private static final byte[] BYTES8 = new byte[8]; + private static final byte[] BYTES16 = new byte[16]; + private static final byte[] BYTES32 = new byte[32]; + private static final byte[] BYTES64 = new byte[64]; + private static final byte[] BYTES128 = new byte[128]; + private static final byte[] BYTES256 = new byte[256]; + private static final byte[] BYTES512 = new byte[512]; + private static final byte[] BYTES1024 = new byte[1024]; + private static final byte[] BYTES2048 = new byte[2048]; + private static final byte[] BYTES4096 = new byte[4096]; + private static final byte[] BYTES8192 = new byte[8192]; + + static { + final Random random = new Random(); + random.nextBytes(BYTES8); + random.nextBytes(BYTES16); + random.nextBytes(BYTES32); + random.nextBytes(BYTES64); + random.nextBytes(BYTES128); + random.nextBytes(BYTES256); + random.nextBytes(BYTES512); + random.nextBytes(BYTES1024); + random.nextBytes(BYTES2048); + random.nextBytes(BYTES4096); + random.nextBytes(BYTES8192); + } + + public static void main(String[] args) throws RunnerException { + Options opt = + new OptionsBuilder().include(BytesToHexBenchmark.class.getSimpleName()).forks(1).build(); + new Runner(opt).run(); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes8ToHex() { + Strings.hex(BYTES8); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes16ToHex() { + Strings.hex(BYTES16); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes32ToHex() { + Strings.hex(BYTES32); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes64ToHex() { + Strings.hex(BYTES64); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes128ToHex() { + Strings.hex(BYTES128); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes256ToHex() { + Strings.hex(BYTES256); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes512ToHex() { + Strings.hex(BYTES512); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes1024ToHex() { + Strings.hex(BYTES1024); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes2048ToHex() { + Strings.hex(BYTES2048); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes4096ToHex() { + Strings.hex(BYTES4096); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void bytes8192ToHex() { + Strings.hex(BYTES8192); + } +} diff --git a/tests/src/test/java/pcap/tests/HexToBytesBenchmark.java b/tests/src/test/java/pcap/tests/HexToBytesBenchmark.java new file mode 100644 index 00000000..41849282 --- /dev/null +++ b/tests/src/test/java/pcap/tests/HexToBytesBenchmark.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2020-2023 Pcap Project + * SPDX-License-Identifier: MIT OR Apache-2.0 + */ +package pcap.tests; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import pcap.common.util.Hexs; +import pcap.common.util.Strings; + +import java.util.Random; + +public class HexToBytesBenchmark { + + private static final String STR8; + private static final String STR16; + private static final String STR32; + private static final String STR64; + private static final String STR128; + private static final String STR256; + private static final String STR512; + private static final String STR1024; + private static final String STR2048; + private static final String STR4096; + private static final String STR8192; + + static { + final byte[] BYTES8 = new byte[8]; + final byte[] BYTES16 = new byte[16]; + final byte[] BYTES32 = new byte[32]; + final byte[] BYTES64 = new byte[64]; + final byte[] BYTES128 = new byte[128]; + final byte[] BYTES256 = new byte[256]; + final byte[] BYTES512 = new byte[512]; + final byte[] BYTES1024 = new byte[1024]; + final byte[] BYTES2048 = new byte[2048]; + final byte[] BYTES4096 = new byte[4096]; + final byte[] BYTES8192 = new byte[8192]; + final Random random = new Random(); + random.nextBytes(BYTES8); + random.nextBytes(BYTES16); + random.nextBytes(BYTES32); + random.nextBytes(BYTES64); + random.nextBytes(BYTES128); + random.nextBytes(BYTES256); + random.nextBytes(BYTES512); + random.nextBytes(BYTES1024); + random.nextBytes(BYTES2048); + random.nextBytes(BYTES4096); + random.nextBytes(BYTES8192); + STR8 = Strings.hex(BYTES8); + STR16 = Strings.hex(BYTES8); + STR32 = Strings.hex(BYTES8); + STR64 = Strings.hex(BYTES8); + STR128 = Strings.hex(BYTES8); + STR256 = Strings.hex(BYTES8); + STR512 = Strings.hex(BYTES8); + STR1024 = Strings.hex(BYTES8); + STR2048 = Strings.hex(BYTES8); + STR4096 = Strings.hex(BYTES8); + STR8192 = Strings.hex(BYTES8); + } + + public static void main(String[] args) throws RunnerException { + Options opt = + new OptionsBuilder().include(HexToBytesBenchmark.class.getSimpleName()).forks(1).build(); + new Runner(opt).run(); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str8ToBytes() { + Hexs.parseHex(STR8); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str16ToBytes() { + Hexs.parseHex(STR16); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str32ToBytes() { + Hexs.parseHex(STR32); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str64ToBytes() { + Hexs.parseHex(STR64); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str128ToBytes() { + Hexs.parseHex(STR128); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str256ToBytes() { + Hexs.parseHex(STR256); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str512ToBytes() { + Hexs.parseHex(STR512); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str1024ToBytes() { + Hexs.parseHex(STR1024); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str2048ToBytes() { + Hexs.parseHex(STR2048); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str4096ToBytes() { + Hexs.parseHex(STR4096); + } + + @Warmup(iterations = 2) // Warmup Iteration = 3 + @Measurement(iterations = 3) + @Benchmark + @BenchmarkMode(Mode.Throughput) + public void str8192ToBytes() { + Hexs.parseHex(STR8192); + } +} From ea9235e09b6a369b40d28c7fe30c38d6c515f614 Mon Sep 17 00:00:00 2001 From: Ardika Rommy Sanjaya Date: Sat, 7 Jan 2023 13:31:16 +0700 Subject: [PATCH 2/6] Add bpf_dump --- .../jdk7/internal/BerkeleyPacketFilter.java | 32 +++++++++++++++++++ .../pcap/jdk7/internal/NativeMappings.java | 20 +++++++++++- .../internal/BerkleyPacketFilterTest.java | 26 +++++++++++++++ spi/src/main/java/pcap/spi/PacketFilter.java | 13 ++++++++ .../java/pcap/tests/BytesToHexBenchmark.java | 4 +-- .../java/pcap/tests/HexToBytesBenchmark.java | 3 +- 6 files changed, 92 insertions(+), 6 deletions(-) diff --git a/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java b/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java index 035ec022..c976b2e7 100644 --- a/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java +++ b/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java @@ -14,6 +14,7 @@ import pcap.spi.PacketBuffer; import pcap.spi.PacketFilter; import pcap.spi.exception.ErrorException; +import pcap.spi.util.Consumer; class BerkeleyPacketFilter implements PacketFilter { @@ -72,6 +73,20 @@ public boolean filter(PacketBuffer packetBuffer) { return r != 0 && r != 4294967295L; } + @Override + public void dump(Consumer consumer) { + fp.bf_insns.read(); + final int n = fp.bf_len; + NativeMappings.bpf_insn.ByReference insn = fp.bf_insns; + int size = insn.size(); + for (int i = 0; i < n; i++) { + consumer.accept(NativeMappings.bpf_image(insn, i)); + final Pointer pointer = insn.getPointer().share(size); + insn = new NativeMappings.bpf_insn.ByReference(pointer); + insn.read(); + } + } + @Override public void close() throws Exception { checkOpenState(); @@ -79,6 +94,23 @@ public void close() throws Exception { cleaner.pointer = 0L; } + @Override + public String toString() { + fp.bf_insns.read(); + final int n = fp.bf_len; + NativeMappings.bpf_insn.ByReference insn = fp.bf_insns; + final StringBuilder sb = new StringBuilder(); + final int size = insn.size(); + sb.append(n).append('\n'); + for (int i = 0; i < n; i++) { + sb.append(String.format("%d %d %d %d\n", insn.code, insn.jt, insn.jf, insn.k)); + final Pointer pointer = insn.getPointer().share(size); + insn = new NativeMappings.bpf_insn.ByReference(pointer); + insn.read(); + } + return sb.toString(); + } + void checkOpenState() { if (cleaner.pointer == 0L) { throw new IllegalStateException("Bpf program is closed."); diff --git a/jdk7/src/main/java/pcap/jdk7/internal/NativeMappings.java b/jdk7/src/main/java/pcap/jdk7/internal/NativeMappings.java index 1bfb6b6d..f7c6da1c 100644 --- a/jdk7/src/main/java/pcap/jdk7/internal/NativeMappings.java +++ b/jdk7/src/main/java/pcap/jdk7/internal/NativeMappings.java @@ -320,6 +320,11 @@ static native Pointer pcap_open_live( static native long bpf_filter( NativeMappings.bpf_insn insn, Pointer packet, int oriPktLen, int pktLen); + @NativeSignature( + signature = "char * bpf_image(const struct bpf_insn *p, int n)", + since = @Version(major = 0, minor = 4)) + static native String bpf_image(NativeMappings.bpf_insn insn, int n); + static InetAddress inetAddress(sockaddr sockaddr) { if (sockaddr == null) { return null; @@ -775,6 +780,10 @@ public bpf_insn() { // public constructor } + public bpf_insn(Pointer ptr) { + super(ptr); + } + @Override protected List getFieldOrder() { return Arrays.asList( @@ -784,7 +793,16 @@ protected List getFieldOrder() { "k"); } - public static final class ByReference extends bpf_insn implements Structure.ByReference {} + public static final class ByReference extends bpf_insn implements Structure.ByReference { + + public ByReference() { + super(); + } + + public ByReference(Pointer ptr) { + super(ptr); + } + } } public static class sockaddr extends Structure { diff --git a/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java b/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java index 81e3c9a1..07a00f1d 100644 --- a/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java +++ b/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java @@ -14,6 +14,7 @@ import pcap.spi.Pcap; import pcap.spi.Service; import pcap.spi.option.DefaultLiveOptions; +import pcap.spi.util.Consumer; class BerkleyPacketFilterTest extends BaseTest { @@ -28,6 +29,31 @@ void clean() throws Exception { } } + @Test + void dump() throws Exception { + Service service = Service.Creator.create("PcapService"); + Interface lo = loopbackInterface(service); + try (Pcap live = service.live(lo, new DefaultLiveOptions())) { + BerkeleyPacketFilter bpf = (BerkeleyPacketFilter) live.compile("icmp", false); + final StringBuilder sb = new StringBuilder(); + bpf.dump( + new Consumer() { + @Override + public void accept(String s) { + sb.append(s).append('\n'); + } + }); + String icmpHumanReadable = + "(000) ldh [12]\n(001) jeq #0x800 jt 2\tjf 5\n(002) ldb [23]\n(003) jeq #0x1 jt 4\tjf 5\n(004) ret #65535\n(005) ret #0\n"; + Assertions.assertEquals(icmpHumanReadable, sb.toString()); + String icmpByteCode = + "6\n40 0 0 12\n21 0 3 2048\n48 0 0 23\n21 0 1 1\n6 0 0 65535\n6 0 0 0\n"; + Assertions.assertEquals(icmpByteCode, bpf.toString()); + Assertions.assertNotNull(bpf); + bpf.clean(); + } + } + @Test void close() throws Exception { Service service = Service.Creator.create("PcapService"); diff --git a/spi/src/main/java/pcap/spi/PacketFilter.java b/spi/src/main/java/pcap/spi/PacketFilter.java index 80d5e215..d23cafdc 100644 --- a/spi/src/main/java/pcap/spi/PacketFilter.java +++ b/spi/src/main/java/pcap/spi/PacketFilter.java @@ -4,6 +4,9 @@ */ package pcap.spi; +import pcap.spi.annotation.Incubating; +import pcap.spi.util.Consumer; + /** * Packet filter. * @@ -19,4 +22,14 @@ public interface PacketFilter extends AutoCloseable { * @since 1.5.0 */ boolean filter(PacketBuffer packetBuffer); + + /** + * Dump the compiled packet-matching code in a human readable form. Please mind that although code + * compilation is always DLT-specific, typically it is impossible (and unnecessary) to specify + * which DLT to use for the dump. + * + * @param consumer consumer. + */ + @Incubating + void dump(Consumer consumer); } diff --git a/tests/src/test/java/pcap/tests/BytesToHexBenchmark.java b/tests/src/test/java/pcap/tests/BytesToHexBenchmark.java index 5c56d3c4..bba802da 100644 --- a/tests/src/test/java/pcap/tests/BytesToHexBenchmark.java +++ b/tests/src/test/java/pcap/tests/BytesToHexBenchmark.java @@ -4,16 +4,14 @@ */ package pcap.tests; +import java.util.Random; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import pcap.common.util.Hexs; import pcap.common.util.Strings; -import java.util.Random; - public class BytesToHexBenchmark { private static final byte[] BYTES8 = new byte[8]; diff --git a/tests/src/test/java/pcap/tests/HexToBytesBenchmark.java b/tests/src/test/java/pcap/tests/HexToBytesBenchmark.java index 41849282..177e7c8e 100644 --- a/tests/src/test/java/pcap/tests/HexToBytesBenchmark.java +++ b/tests/src/test/java/pcap/tests/HexToBytesBenchmark.java @@ -4,6 +4,7 @@ */ package pcap.tests; +import java.util.Random; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; @@ -12,8 +13,6 @@ import pcap.common.util.Hexs; import pcap.common.util.Strings; -import java.util.Random; - public class HexToBytesBenchmark { private static final String STR8; From 143a55508be05420bfc9748900113f2fa205200e Mon Sep 17 00:00:00 2001 From: Ardika Rommy Sanjaya Date: Sat, 7 Jan 2023 13:42:49 +0700 Subject: [PATCH 3/6] Check open status --- .../main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java b/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java index c976b2e7..eff467ae 100644 --- a/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java +++ b/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java @@ -75,6 +75,7 @@ public boolean filter(PacketBuffer packetBuffer) { @Override public void dump(Consumer consumer) { + checkOpenState(); fp.bf_insns.read(); final int n = fp.bf_len; NativeMappings.bpf_insn.ByReference insn = fp.bf_insns; @@ -96,6 +97,7 @@ public void close() throws Exception { @Override public String toString() { + checkOpenState(); fp.bf_insns.read(); final int n = fp.bf_len; NativeMappings.bpf_insn.ByReference insn = fp.bf_insns; @@ -103,7 +105,7 @@ public String toString() { final int size = insn.size(); sb.append(n).append('\n'); for (int i = 0; i < n; i++) { - sb.append(String.format("%d %d %d %d\n", insn.code, insn.jt, insn.jf, insn.k)); + sb.append(String.format("%d %d %d %d\n", insn.code, insn.jt, insn.jf, insn.k & 0xffffffffL)); final Pointer pointer = insn.getPointer().share(size); insn = new NativeMappings.bpf_insn.ByReference(pointer); insn.read(); From cb5439171b7fa6b8e76ff19f92151c702f0530d6 Mon Sep 17 00:00:00 2001 From: Ardika Rommy Sanjaya Date: Sat, 7 Jan 2023 13:49:36 +0700 Subject: [PATCH 4/6] Check link type --- .../jdk7/internal/BerkleyPacketFilterTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java b/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java index 07a00f1d..99075664 100644 --- a/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java +++ b/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java @@ -43,12 +43,14 @@ public void accept(String s) { sb.append(s).append('\n'); } }); - String icmpHumanReadable = - "(000) ldh [12]\n(001) jeq #0x800 jt 2\tjf 5\n(002) ldb [23]\n(003) jeq #0x1 jt 4\tjf 5\n(004) ret #65535\n(005) ret #0\n"; - Assertions.assertEquals(icmpHumanReadable, sb.toString()); - String icmpByteCode = - "6\n40 0 0 12\n21 0 3 2048\n48 0 0 23\n21 0 1 1\n6 0 0 65535\n6 0 0 0\n"; - Assertions.assertEquals(icmpByteCode, bpf.toString()); + if (live.datalink() == 1) { + String icmpHumanReadable = + "(000) ldh [12]\n(001) jeq #0x800 jt 2\tjf 5\n(002) ldb [23]\n(003) jeq #0x1 jt 4\tjf 5\n(004) ret #65535\n(005) ret #0\n"; + Assertions.assertEquals(icmpHumanReadable, sb.toString()); + String icmpByteCode = + "6\n40 0 0 12\n21 0 3 2048\n48 0 0 23\n21 0 1 1\n6 0 0 65535\n6 0 0 0\n"; + Assertions.assertEquals(icmpByteCode, bpf.toString()); + } Assertions.assertNotNull(bpf); bpf.clean(); } From 36c24fe233b658669848896f964093ef26e4dcac Mon Sep 17 00:00:00 2001 From: Ardika Rommy Sanjaya Date: Tue, 10 Jan 2023 12:51:39 +0700 Subject: [PATCH 5/6] Get byte code --- .../jdk7/internal/BerkeleyPacketFilter.java | 39 +++++++++++++------ .../internal/BerkleyPacketFilterTest.java | 32 ++++++++++++--- spi/src/main/java/pcap/spi/PacketFilter.java | 8 ++++ 3 files changed, 61 insertions(+), 18 deletions(-) diff --git a/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java b/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java index eff467ae..06543c69 100644 --- a/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java +++ b/jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java @@ -8,9 +8,12 @@ import com.sun.jna.Structure; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; +import java.nio.ByteBuffer; import java.util.Collections; import java.util.HashSet; import java.util.Set; + +import pcap.common.util.Strings; import pcap.spi.PacketBuffer; import pcap.spi.PacketFilter; import pcap.spi.exception.ErrorException; @@ -89,28 +92,40 @@ public void dump(Consumer consumer) { } @Override - public void close() throws Exception { - checkOpenState(); - NativeMappings.pcap_freecode(fp); - cleaner.pointer = 0L; - } - - @Override - public String toString() { + public byte[] bytes() { checkOpenState(); fp.bf_insns.read(); final int n = fp.bf_len; NativeMappings.bpf_insn.ByReference insn = fp.bf_insns; - final StringBuilder sb = new StringBuilder(); final int size = insn.size(); - sb.append(n).append('\n'); + final ByteBuffer buffer = ByteBuffer.allocate(size * n + 4); + buffer.putInt(n); for (int i = 0; i < n; i++) { - sb.append(String.format("%d %d %d %d\n", insn.code, insn.jt, insn.jf, insn.k & 0xffffffffL)); + buffer.putShort(insn.code); + buffer.put(insn.jt); + buffer.put(insn.jf); + buffer.putInt(insn.k); final Pointer pointer = insn.getPointer().share(size); insn = new NativeMappings.bpf_insn.ByReference(pointer); insn.read(); } - return sb.toString(); + return buffer.array(); + } + + @Override + public void close() throws Exception { + checkOpenState(); + NativeMappings.pcap_freecode(fp); + cleaner.pointer = 0L; + } + + @Override + public String toString() { + try { + return Strings.hex(bytes()); + } catch (Exception e) { + return ""; + } } void checkOpenState() { diff --git a/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java b/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java index 99075664..74a0e512 100644 --- a/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java +++ b/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; import pcap.common.util.Hexs; +import pcap.common.util.Strings; import pcap.spi.Interface; import pcap.spi.PacketBuffer; import pcap.spi.PacketFilter; @@ -44,12 +45,17 @@ public void accept(String s) { } }); if (live.datalink() == 1) { - String icmpHumanReadable = - "(000) ldh [12]\n(001) jeq #0x800 jt 2\tjf 5\n(002) ldb [23]\n(003) jeq #0x1 jt 4\tjf 5\n(004) ret #65535\n(005) ret #0\n"; - Assertions.assertEquals(icmpHumanReadable, sb.toString()); - String icmpByteCode = - "6\n40 0 0 12\n21 0 3 2048\n48 0 0 23\n21 0 1 1\n6 0 0 65535\n6 0 0 0\n"; - Assertions.assertEquals(icmpByteCode, bpf.toString()); + final String str = "(000) ldh [12]\n" + + "(001) jeq #0x800 jt 2\tjf 5\n" + + "(002) ldb [23]\n" + + "(003) jeq #0x1 jt 4\tjf 5\n" + + "(004) ret #65535\n" + + "(005) ret #0\n"; + Assertions.assertEquals(str, sb.toString()); + } else if (live.datalink() == 113) { + + } else if (live.datalink() == 0) { + } Assertions.assertNotNull(bpf); bpf.clean(); @@ -75,6 +81,20 @@ public void execute() throws Throwable { } } + @Test + void bytes() throws Exception { + final Service service = Service.Creator.create("PcapService"); + final Interface lo = loopbackInterface(service); + try (final Pcap live = service.live(lo, new DefaultLiveOptions())) { + final BerkeleyPacketFilter bpf = (BerkeleyPacketFilter) live.compile("icmp", false); + final byte[] bytes = bpf.bytes(); + final String str = Strings.hex(bytes); + Assertions.assertNotNull(str); + Assertions.assertNotNull(bpf); + bpf.clean(); + } + } + @Test void filter() throws Exception { String hexStream = diff --git a/spi/src/main/java/pcap/spi/PacketFilter.java b/spi/src/main/java/pcap/spi/PacketFilter.java index d23cafdc..1594f8dd 100644 --- a/spi/src/main/java/pcap/spi/PacketFilter.java +++ b/spi/src/main/java/pcap/spi/PacketFilter.java @@ -32,4 +32,12 @@ public interface PacketFilter extends AutoCloseable { */ @Incubating void dump(Consumer consumer); + + /** + * Get byte code. + * + * @return returns byte code. + */ + @Incubating + byte[] bytes(); } From b7575f9d760e610b193775a7c6c4d30ee95c4a63 Mon Sep 17 00:00:00 2001 From: Ardika Rommy Sanjaya Date: Tue, 10 Jan 2023 12:56:56 +0700 Subject: [PATCH 6/6] Refactor tests --- .../internal/BerkleyPacketFilterTest.java | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java b/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java index 74a0e512..c254535c 100644 --- a/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java +++ b/jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java @@ -35,30 +35,30 @@ void dump() throws Exception { Service service = Service.Creator.create("PcapService"); Interface lo = loopbackInterface(service); try (Pcap live = service.live(lo, new DefaultLiveOptions())) { - BerkeleyPacketFilter bpf = (BerkeleyPacketFilter) live.compile("icmp", false); - final StringBuilder sb = new StringBuilder(); - bpf.dump( - new Consumer() { - @Override - public void accept(String s) { - sb.append(s).append('\n'); - } - }); - if (live.datalink() == 1) { - final String str = "(000) ldh [12]\n" + - "(001) jeq #0x800 jt 2\tjf 5\n" + - "(002) ldb [23]\n" + - "(003) jeq #0x1 jt 4\tjf 5\n" + - "(004) ret #65535\n" + - "(005) ret #0\n"; - Assertions.assertEquals(str, sb.toString()); - } else if (live.datalink() == 113) { + try (BerkeleyPacketFilter bpf = (BerkeleyPacketFilter) live.compile("icmp", false)) { + final StringBuilder sb = new StringBuilder(); + bpf.dump( + new Consumer() { + @Override + public void accept(String s) { + sb.append(s).append('\n'); + } + }); + if (live.datalink() == 1) { + final String str = "(000) ldh [12]\n" + + "(001) jeq #0x800 jt 2\tjf 5\n" + + "(002) ldb [23]\n" + + "(003) jeq #0x1 jt 4\tjf 5\n" + + "(004) ret #65535\n" + + "(005) ret #0\n"; + Assertions.assertEquals(str, sb.toString()); + } else if (live.datalink() == 113) { - } else if (live.datalink() == 0) { + } else if (live.datalink() == 0) { + } + Assertions.assertNotNull(bpf); } - Assertions.assertNotNull(bpf); - bpf.clean(); } } @@ -86,12 +86,12 @@ void bytes() throws Exception { final Service service = Service.Creator.create("PcapService"); final Interface lo = loopbackInterface(service); try (final Pcap live = service.live(lo, new DefaultLiveOptions())) { - final BerkeleyPacketFilter bpf = (BerkeleyPacketFilter) live.compile("icmp", false); - final byte[] bytes = bpf.bytes(); - final String str = Strings.hex(bytes); - Assertions.assertNotNull(str); - Assertions.assertNotNull(bpf); - bpf.clean(); + try (final BerkeleyPacketFilter bpf = (BerkeleyPacketFilter) live.compile("icmp", false)) { + final byte[] bytes = bpf.bytes(); + final String str = Strings.hex(bytes); + Assertions.assertNotNull(str); + Assertions.assertNotNull(bpf); + } } }