Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions codec/src/main/java/pcap/codec/ethernet/Ethernet.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand Down
17 changes: 10 additions & 7 deletions common/src/main/java/pcap/common/net/MacAddress.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -99,7 +99,7 @@ public static MacAddress fromString(String stringAddress) {
bytes[offset] = (byte) ((hi << 4) + lo);
offset += 1;
}
return valueOf(bytes);
return fromBytes(bytes);
}

/**
Expand All @@ -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.");
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -175,7 +178,7 @@ public static MacAddress fromLong(final long longAddress) {
(byte) (longAddress >> 8 & 0xff),
(byte) (longAddress & 0xff)
};
return valueOf(bytes);
return fromBytes(bytes);
}

/**
Expand Down
49 changes: 49 additions & 0 deletions jdk7/src/main/java/pcap/jdk7/internal/BerkeleyPacketFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
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;
import pcap.spi.util.Consumer;

class BerkeleyPacketFilter implements PacketFilter {

Expand Down Expand Up @@ -72,13 +76,58 @@ public boolean filter(PacketBuffer packetBuffer) {
return r != 0 && r != 4294967295L;
}

@Override
public void dump(Consumer<String> consumer) {
checkOpenState();
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 byte[] bytes() {
checkOpenState();
fp.bf_insns.read();
final int n = fp.bf_len;
NativeMappings.bpf_insn.ByReference insn = fp.bf_insns;
final int size = insn.size();
final ByteBuffer buffer = ByteBuffer.allocate(size * n + 4);
buffer.putInt(n);
for (int i = 0; i < n; i++) {
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 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() {
if (cleaner.pointer == 0L) {
throw new IllegalStateException("Bpf program is closed.");
Expand Down
20 changes: 19 additions & 1 deletion jdk7/src/main/java/pcap/jdk7/internal/NativeMappings.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -775,6 +780,10 @@ public bpf_insn() {
// public constructor
}

public bpf_insn(Pointer ptr) {
super(ptr);
}

@Override
protected List<String> getFieldOrder() {
return Arrays.asList(
Expand All @@ -784,7 +793,16 @@ protected List<String> 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 {
Expand Down
48 changes: 48 additions & 0 deletions jdk7/src/test/java/pcap/jdk7/internal/BerkleyPacketFilterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
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;
import pcap.spi.Pcap;
import pcap.spi.Service;
import pcap.spi.option.DefaultLiveOptions;
import pcap.spi.util.Consumer;

class BerkleyPacketFilterTest extends BaseTest {

Expand All @@ -28,6 +30,38 @@ 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())) {
try (BerkeleyPacketFilter bpf = (BerkeleyPacketFilter) live.compile("icmp", false)) {
final StringBuilder sb = new StringBuilder();
bpf.dump(
new Consumer<String>() {
@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) {

}
Assertions.assertNotNull(bpf);
}
}
}

@Test
void close() throws Exception {
Service service = Service.Creator.create("PcapService");
Expand All @@ -47,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())) {
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);
}
}
}

@Test
void filter() throws Exception {
String hexStream =
Expand Down
21 changes: 21 additions & 0 deletions spi/src/main/java/pcap/spi/PacketFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*/
package pcap.spi;

import pcap.spi.annotation.Incubating;
import pcap.spi.util.Consumer;

/**
* Packet filter.
*
Expand All @@ -19,4 +22,22 @@ 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<String> consumer);

/**
* Get byte code.
*
* @return returns byte code.
*/
@Incubating
byte[] bytes();
}
Loading