Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
* Pcap capture multiplexor
*
* @author ETSI / STF424
* @version $URL$
* $Id$
* Note Copy jnetpcap.jar in C:\WINDOWS\Sun\Java\lib\ext, location of jpcap library
*/
package org.etsi.its.pcapdump;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.etsi.common.ByteHelper;
import org.jnetpcap.Pcap;
import org.jnetpcap.PcapBpfProgram;
import org.jnetpcap.PcapDumper;
import org.jnetpcap.PcapIf;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
public class PcapMultiplexer implements Runnable {
private static String ExpectedIface = "D4BED91269BD";
/**
* Unique instance of the factory
*/
private static PcapMultiplexer instance = null;
private StringBuilder errbuf = new StringBuilder(); // For any error msgs
private ILayer _client;
private PcapDumper dumper;
private PcapMultiplexer() {
filter = "";
// Obtain the list of network interfaces
List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
int r = Pcap.findAllDevs(alldevs, errbuf);
if (r != Pcap.OK || alldevs.isEmpty()) {
System.err.printf("Can't read list of devices, error is %s", errbuf.toString());
return;
}
// Find the right interface
int ifaceIndex = 0;
String expectedIface = PcapMultiplexer.ExpectedIface;
for( ; ifaceIndex < alldevs.size(); ifaceIndex++) {
try {
if (expectedIface.equalsIgnoreCase(ByteHelper.byteArrayToString(alldevs.get(ifaceIndex).getHardwareAddress()))) {
// Interface found
break;
}
} catch (IOException e) {
// ignore
}
}
// Check result
if (ifaceIndex == alldevs.size()) {
throw new RuntimeException(String.format("EthernetLayer.register: Network interface %s not found", expectedIface));
}
device = alldevs.get(ifaceIndex);
System.out.println("Listening: " + device.getName());
}
/**
* Gets the unique factory instance
* @return PcapMultiplexer instance
*/
public static PcapMultiplexer getInstance(final String macAddress){
ExpectedIface = macAddress;
return (instance = new PcapMultiplexer());
}
/**
* Gets the unique factory instance
* @return PcapMultiplexer instance
*/
public static PcapMultiplexer getInstance(){
return instance;
}
public synchronized void register(ILayer client, short frameType) {
// Open interface
int snaplen = 64 * 1024; // Capture all packets, no truncation
int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
int timeout = 10; // 10 millis
pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errbuf);
if (pcap == null) {
System.err.printf("Error while opening device for capture: " + errbuf.toString());
return;
}
captureThread = new Thread(this);
captureThread.start();
filter = String.format("ether proto 0x%04x", frameType);
System.out.println("New filter: " + filter);
// Apply filter
PcapBpfProgram bpfFilter = new PcapBpfProgram();
int optimize = 0; // 1 means true, 0 means false
int netmask = 0;
int r = pcap.compile(bpfFilter, filter, optimize, netmask);
if (r != Pcap.OK) {
System.out.println("Filter error: " + pcap.getErr());
}
pcap.setFilter(bpfFilter);
dumper = pcap.dumpOpen(client.getFileName());
_client = client;
}
public synchronized void unregister(ILayer client) {
pcap.breakloop();
dumper.close();
try {
captureThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
pcap.close();
}
/**
* Thread function for jpcap capture loop
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
PcapPacketHandler<String> dumpHandler = new PcapPacketHandler<String>() {
private int counter = 0;
@Override
public void nextPacket(PcapPacket packet, String user) {
dumper.dump(packet);
counter += 1;
if (counter == 500) {
System.out.println("nextPacket: Flushing file");
dumper.flush();
counter = 0;
}
}
};
pcap.loop(-1, dumpHandler, "pcapdump");
}
/**
* Jpcap capture device
*/
private Pcap pcap;
/**
* Jpcap capture thread instance.
*/
private Thread captureThread;
PcapIf device;
private String filter;
}