Skip to content

Commit

Permalink
Mac address detection on Windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
kaitoy committed Dec 6, 2015
1 parent d82675a commit 97002a6
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 12 deletions.
3 changes: 2 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Future
======
### New Features ###
* [Issues#49](https://github.com/kaitoy/pcap4j/issues/49): Add PcapHandle.getOriginalLength().
* [Issues#48](https://github.com/kaitoy/pcap4j/issues/48): Add PcapHandle.getOriginalLength().
* [Issues#49](https://github.com/kaitoy/pcap4j/issues/49): Mac address detection on Windows.

### Bug Fixes ###

Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Contents
* [Documents](#documents)
* [How to run samples](#how-to-run-samples)
* [How to use in Maven project](#how-to-use-in-maven-project)
* [About pcap library loading](#about-pcap-library-loading)
* [About native library loading](#about-native-library-loading)
* [Docker](#docker)
* [How to build](#how-to-build)
* [Build procedure with Maven command (recommended)](#build-procedure-with-maven-command-recommended)
Expand Down Expand Up @@ -178,12 +178,12 @@ Add a dependency to the pom.xml as like below:
</project>
```

#### About pcap library loading ####
By default, Pcap4j loads the pcap library on the following conditions:
#### About native library loading ####
By default, Pcap4j loads the native libraries on the following conditions:

* Windows
* search path: The paths in the `PATH` environment variable.
* file name: wpcap.dll
* file name: wpcap.dll and Packet.dll
* Linux/UNIX
* search path: The search paths of shared libraries configured on the OS.
(e.g. The paths in the `LD_LIBRARY_PATH` environment variable)
Expand All @@ -195,8 +195,9 @@ By default, Pcap4j loads the pcap library on the following conditions:

You can use the following Java system properties to change the default behavior.

* jna.library.path: Specify the search path
* org.pcap4j.core.pcapLibName: Specify the full path of the pcap library
* jna.library.path: The search path
* org.pcap4j.core.pcapLibName: The full path of the pcap library (wpcap.dll, libpcap.so, or libpcap.dylib)
* (Windows only) org.pcap4j.core.packetLibName: The full path of the packet library (Packet.dll)

### Docker ###
A Docker image for Pcap4J on CentOS is available at [Docker Hub](https://registry.hub.docker.com/u/kaitoy/pcap4j/).
Expand Down
11 changes: 6 additions & 5 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Pcap4J
* [ドキュメント](#ドキュメント)
* [サンプル実行方法](#サンプル実行方法)
* [Mavenプロジェクトでの使用方法](#mavenプロジェクトでの使用方法)
* [pcapライブラリのロードについて](#pcapライブラリのロードについて)
* [ネイティブライブラリのロードについて](#ネイティブライブラリのロードについて)
* [Docker](#docker)
* [ビルド](#ビルド)
* [Mavenコマンドでのビルド手順 (推奨)](#mavenコマンドでのビルド手順-推奨)
Expand Down Expand Up @@ -180,12 +180,12 @@ pom.xmlに以下のような記述を追加する。
</project>
```

#### pcapライブラリのロードについて ####
デフォルトでは下記の条件でpcapライブラリを検索し、ロードする。
#### ネイティブライブラリのロードについて ####
デフォルトでは下記の条件でネイティブライブラリを検索し、ロードする。

* Windows
* サーチパス: 環境変数`PATH`に含まれるパス。
* ファイル名: wpcap.dll
* ファイル名: wpcap.dllとPacket.dll
* Linux/UNIX
* サーチパス: OSに設定された共有ライブラリのサーチパス。例えば環境変数`LD_LIBRARY_PATH`に含まれるパス。
* ファイル名: libpcap.so
Expand All @@ -196,7 +196,8 @@ pom.xmlに以下のような記述を追加する。
カスタマイズのために、以下のJavaのシステムプロパティが使える。

* jna.library.path: サーチパスを指定する。
* org.pcap4j.core.pcapLibName: ライブラリへのフルパスを指定する。
* org.pcap4j.core.pcapLibName: pcapライブラリ(wpcap.dllかlibpcap.soかlibpcap.dylib)へのフルパスを指定する。
* (Windowsのみ) org.pcap4j.core.packetLibName: packetライブラリ(Packet.dll)へのフルパスを指定する。

### Docker ###
CentOSのPcap4J実行環境を構築したDockerイメージが[Docker Hub](https://registry.hub.docker.com/u/kaitoy/pcap4j/)にある。
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*_##########################################################################
_##
_## Copyright (C) 2015 Pcap4J.org
_##
_##########################################################################
*/

package org.pcap4j.core;

import java.util.ArrayList;
import java.util.List;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;

/**
* @author Kaito Yamada
* @since pcap4j 1.6.2
*/
final class NativePacketDllMappings {

static final String LIB_NAME
= System.getProperty(
NativePacketDllMappings.class.getPackage().getName() + ".packetLibName",
"Packet"
);

static final int PACKET_OID_DATA_SIZE;

static {
Native.register(
NativePacketDllMappings.class,
NativeLibrary.getInstance(LIB_NAME)
);

PACKET_OID_DATA_SIZE = new PACKET_OID_DATA().size();
}

// LPADAPTER PacketOpenAdapter(PCHAR AdapterNameWA)
static native Pointer PacketOpenAdapter(String AdapterNameWA);

// BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData)
static native int PacketRequest(Pointer AdapterObject, int Set, PACKET_OID_DATA OidData);

// VOID PacketCloseAdapter(LPADAPTER lpAdapter)
static native void PacketCloseAdapter(Pointer lpAdapter);

// struct _PACKET_OID_DATA {
// ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h
// ///< for a complete list of valid codes.
// ULONG Length; ///< Length of the data field
// UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received
// ///< from the adapter.
// };
public static class PACKET_OID_DATA extends Structure {

public NativeLong Oid; // ULONG
public NativeLong Length; // ULONG
public byte[] Data = new byte[6]; // UCHAR

public PACKET_OID_DATA() {}

public PACKET_OID_DATA(Pointer p) {
super(p);
read();
}

public static
class ByReference
extends PACKET_OID_DATA implements Structure.ByReference {}

@Override
protected List<String> getFieldOrder() {
List<String> list = new ArrayList<String>();
list.add("Oid");
list.add("Length");
list.add("Data");
return list;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
import org.pcap4j.core.NativeMappings.sockaddr_dl;
import org.pcap4j.core.NativeMappings.sockaddr_ll;
import org.pcap4j.core.NativeMappings.timeval;
import org.pcap4j.core.NativePacketDllMappings.PACKET_OID_DATA;
import org.pcap4j.core.PcapHandle.TimestampPrecision;
import org.pcap4j.util.ByteArrays;
import org.pcap4j.util.LinkLayerAddress;
import org.pcap4j.util.MacAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
Expand Down Expand Up @@ -116,6 +119,13 @@ else if (addr.length == 0) {
}
}

if (Platform.isWindows()) {
MacAddress mac = getMacAddress(name);
if (mac != null) {
linkLayerAddresses.add(mac);
}
}

if (pif.flags == PCAP_IF_LOOPBACK) {
this.loopBack = true;
}
Expand Down Expand Up @@ -274,6 +284,41 @@ public PcapHandle openLive(
return new PcapHandle(handle, TimestampPrecision.MICRO);
}

private MacAddress getMacAddress(String nifName) {
Pointer lpAdapter = NativePacketDllMappings.PacketOpenAdapter(nifName);

long hFile = -1;
if (lpAdapter != null) {
if (Pointer.SIZE == 4) {
hFile = lpAdapter.getInt(0);
}
else {
hFile = lpAdapter.getLong(0);
}
}
if (hFile == -1L) {
int err = Native.getLastError();
logger.error("Unable to open the NIF {}, Error Code: {}", nifName, err);
return null;
}

Memory mem = new Memory(NativePacketDllMappings.PACKET_OID_DATA_SIZE);
mem.clear();
PACKET_OID_DATA oidData = new PACKET_OID_DATA(mem);
oidData.Length = new NativeLong(6L);
oidData.Oid = new NativeLong(0x01010102L);
int status = NativePacketDllMappings.PacketRequest(lpAdapter, 0, oidData);
NativePacketDllMappings.PacketCloseAdapter(lpAdapter);

if (status == 0) {
logger.error("Failed to retrieve the link layer address of the NIF: {}", nifName);
return null;
}
else {
return MacAddress.getByAddress(oidData.Data);
}
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder(250);
Expand Down

0 comments on commit 97002a6

Please sign in to comment.