KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > fenyo > gnetwatch > activities > Capture


1
2 /*
3  * GNetWatch
4  * Copyright 2006, 2007 Alexandre Fenyo
5  * gnetwatch@fenyo.net
6  *
7  * This file is part of GNetWatch.
8  *
9  * GNetWatch is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * GNetWatch is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with GNetWatch; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22  */

23
24 package net.fenyo.gnetwatch.activities;
25
26 import net.fenyo.gnetwatch.*;
27 import net.fenyo.gnetwatch.actions.ExternalCommand;
28 import net.fenyo.gnetwatch.data.EventReachable;
29
30 import java.util.*;
31 import java.util.regex.Matcher JavaDoc;
32 import java.util.regex.Pattern JavaDoc;
33 import java.io.*;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38 import org.dom4j.*;
39 import org.dom4j.io.*;
40
41 /*
42  * XPATH doc: http://xmlfr.org/w3c/TR/xpath/
43  * XPATH ex.: IP src address : "string(//field[@name='ip.addr'][1]/@show)"
44  * PDML packet example:
45   <packet>
46   <proto name="geninfo" pos="0" showname="General information" size="74">
47     <field name="num" pos="0" show="1" showname="Number" value="1" size="74"/>
48     <field name="len" pos="0" show="74" showname="Packet Length" value="4a" size="74"/>
49     <field name="caplen" pos="0" show="74" showname="Captured Length" value="4a" size="74"/>
50     <field name="timestamp" pos="0" show="Dec 27, 2006 18:30:17.657143000" showname="Captured Time" value="1167240617.657143000" size="74"/>
51   </proto>
52   <proto name="frame" showname="Frame 1 (74 bytes on wire, 74 bytes captured)" size="74" pos="0">
53     <field name="frame.marked" showname="Frame is marked: False" hide="yes" size="0" pos="0" show="0"/>
54     <field name="frame.time" showname="Arrival Time: Dec 27, 2006 18:30:17.657143000" size="0" pos="0" show="Dec 27, 2006 18:30:17.657143000"/>
55     <field name="frame.time_delta" showname="Time delta from previous packet: 0.000000000 seconds" size="0" pos="0" show="0.000000000"/>
56     <field name="frame.time_relative" showname="Time since reference or first frame: 0.000000000 seconds" size="0" pos="0" show="0.000000000"/>
57     <field name="frame.number" showname="Frame Number: 1" size="0" pos="0" show="1"/>
58     <field name="frame.pkt_len" showname="Packet Length: 74 bytes" size="0" pos="0" show="74"/>
59     <field name="frame.cap_len" showname="Capture Length: 74 bytes" size="0" pos="0" show="74"/>
60     <field name="frame.protocols" showname="Protocols in frame: eth:ip:tcp" size="0" pos="0" show="eth:ip:tcp"/>
61   </proto>
62   <proto name="eth" showname="Ethernet II, Src: Netgear_fb:43:4f (00:0f:b5:fb:43:4f), Dst: AsustekC_54:cf:69 (00:11:d8:54:cf:69)" size="14" pos="0">
63     <field name="eth.dst" showname="Destination: AsustekC_54:cf:69 (00:11:d8:54:cf:69)" size="6" pos="0" show="00:11:d8:54:cf:69" value="0011d854cf69"/>
64     <field name="eth.src" showname="Source: Netgear_fb:43:4f (00:0f:b5:fb:43:4f)" size="6" pos="6" show="00:0f:b5:fb:43:4f" value="000fb5fb434f"/>
65     <field name="eth.addr" showname="Source or Destination Address: AsustekC_54:cf:69 (00:11:d8:54:cf:69)" hide="yes" size="6" pos="0" show="00:11:d8:54:cf:69" value="0011d854cf69"/>
66     <field name="eth.addr" showname="Source or Destination Address: Netgear_fb:43:4f (00:0f:b5:fb:43:4f)" hide="yes" size="6" pos="6" show="00:0f:b5:fb:43:4f" value="000fb5fb434f"/>
67     <field name="eth.type" showname="Type: IP (0x0800)" size="2" pos="12" show="0x0800" value="0800"/>
68   </proto>
69   <proto name="ip" showname="Internet Protocol, Src: 192.168.0.53 (192.168.0.53), Dst: 192.168.0.29 (192.168.0.29)" size="20" pos="14">
70     <field name="ip.version" showname="Version: 4" size="1" pos="14" show="4" value="45"/>
71     <field name="ip.hdr_len" showname="Header length: 20 bytes" size="1" pos="14" show="20" value="45"/>
72     <field name="ip.dsfield" showname="Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)" size="1" pos="15" show="0" value="00">
73       <field name="ip.dsfield.dscp" showname="0000 00.. = Differentiated Services Codepoint: Default (0x00)" size="1" pos="15" show="0x00" value="0" unmaskedvalue="00"/>
74       <field name="ip.dsfield.ect" showname=".... ..0. = ECN-Capable Transport (ECT): 0" size="1" pos="15" show="0" value="0" unmaskedvalue="00"/>
75       <field name="ip.dsfield.ce" showname=".... ...0 = ECN-CE: 0" size="1" pos="15" show="0" value="0" unmaskedvalue="00"/>
76     </field>
77     <field name="ip.len" showname="Total Length: 60" size="2" pos="16" show="60" value="003c"/>
78     <field name="ip.id" showname="Identification: 0xad9f (44447)" size="2" pos="18" show="0xad9f" value="ad9f"/>
79     <field name="ip.flags" showname="Flags: 0x04 (Don&apos;t Fragment)" size="1" pos="20" show="0x04" value="40">
80       <field name="ip.flags.rb" showname="0... = Reserved bit: Not set" size="1" pos="20" show="0" value="0" unmaskedvalue="40"/>
81       <field name="ip.flags.df" showname=".1.. = Don&apos;t fragment: Set" size="1" pos="20" show="1" value="1" unmaskedvalue="40"/>
82       <field name="ip.flags.mf" showname="..0. = More fragments: Not set" size="1" pos="20" show="0" value="0" unmaskedvalue="40"/>
83     </field>
84     <field name="ip.frag_offset" showname="Fragment offset: 0" size="2" pos="20" show="0" value="4000"/>
85     <field name="ip.ttl" showname="Time to live: 64" size="1" pos="22" show="64" value="40"/>
86     <field name="ip.proto" showname="Protocol: TCP (0x06)" size="1" pos="23" show="0x06" value="06"/>
87     <field name="ip.checksum" showname="Header checksum: 0x0b7a [correct]" size="2" pos="24" show="0x0b7a" value="0b7a"/>
88     <field name="ip.src" showname="Source: 192.168.0.53 (192.168.0.53)" size="4" pos="26" show="192.168.0.53" value="c0a80035"/>
89     <field name="ip.addr" showname="Source or Destination Address: 192.168.0.53 (192.168.0.53)" hide="yes" size="4" pos="26" show="192.168.0.53" value="c0a80035"/>
90     <field name="ip.src_host" showname="Source Host: 192.168.0.53" hide="yes" size="4" pos="26" show="192.168.0.53" value="c0a80035"/>
91     <field name="ip.host" showname="Source or Destination Host: 192.168.0.53" hide="yes" size="4" pos="26" show="192.168.0.53" value="c0a80035"/>
92     <field name="ip.dst" showname="Destination: 192.168.0.29 (192.168.0.29)" size="4" pos="30" show="192.168.0.29" value="c0a8001d"/>
93     <field name="ip.addr" showname="Source or Destination Address: 192.168.0.29 (192.168.0.29)" hide="yes" size="4" pos="30" show="192.168.0.29" value="c0a8001d"/>
94     <field name="ip.dst_host" showname="Destination Host: 192.168.0.29" hide="yes" size="4" pos="30" show="192.168.0.29" value="c0a8001d"/>
95     <field name="ip.host" showname="Source or Destination Host: 192.168.0.29" hide="yes" size="4" pos="30" show="192.168.0.29" value="c0a8001d"/>
96   </proto>
97   <proto name="tcp" showname="Transmission Control Protocol, Src Port: 34604 (34604), Dst Port: 6001 (6001), Seq: 0, Ack: 0, Len: 0" size="40" pos="34">
98     <field name="tcp.srcport" showname="Source port: 34604 (34604)" size="2" pos="34" show="34604" value="872c"/>
99     <field name="tcp.dstport" showname="Destination port: 6001 (6001)" size="2" pos="36" show="6001" value="1771"/>
100     <field name="tcp.port" showname="Source or Destination Port: 34604" hide="yes" size="2" pos="34" show="34604" value="872c"/>
101     <field name="tcp.port" showname="Source or Destination Port: 6001" hide="yes" size="2" pos="36" show="6001" value="1771"/>
102     <field name="tcp.len" showname="TCP Segment Len: 0" hide="yes" size="4" pos="34" show="0" value="872c1771"/>
103     <field name="tcp.seq" showname="Sequence number: 0 (relative sequence number)" size="4" pos="38" show="0" value="d64b4fd4"/>
104     <field name="tcp.hdr_len" showname="Header length: 40 bytes" size="1" pos="46" show="40" value="a0"/>
105     <field name="tcp.flags" showname="Flags: 0x00c2 (SYN, ECN, CWR)" size="1" pos="47" show="0xc2" value="c2">
106       <field name="tcp.flags.cwr" showname="1... .... = Congestion Window Reduced (CWR): Set" size="1" pos="47" show="1" value="1" unmaskedvalue="c2"/>
107       <field name="tcp.flags.ecn" showname=".1.. .... = ECN-Echo: Set" size="1" pos="47" show="1" value="1" unmaskedvalue="c2"/>
108       <field name="tcp.flags.urg" showname="..0. .... = Urgent: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="c2"/>
109       <field name="tcp.flags.ack" showname="...0 .... = Acknowledgment: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="c2"/>
110       <field name="tcp.flags.push" showname=".... 0... = Push: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="c2"/>
111       <field name="tcp.flags.reset" showname=".... .0.. = Reset: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="c2"/>
112       <field name="tcp.flags.syn" showname=".... ..1. = Syn: Set" size="1" pos="47" show="1" value="1" unmaskedvalue="c2"/>
113       <field name="tcp.flags.fin" showname=".... ...0 = Fin: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="c2"/>
114     </field>
115     <field name="tcp.window_size" showname="Window size: 5840" size="2" pos="48" show="5840" value="16d0"/>
116     <field name="tcp.checksum" showname="Checksum: 0xfd91 [correct]" size="2" pos="50" show="0xfd91" value="fd91"/>
117     <field show="Options: (20 bytes)" size="20" pos="54" value="020405b40402080a0a39e24b0000000001030300">
118       <field name="tcp.options.mss" showname="TCP MSS Option: True" hide="yes" size="4" pos="54" show="1" value="020405b4"/>
119       <field name="tcp.options.mss_val" showname="Maximum segment size: 1460 bytes" size="4" pos="54" show="1460" value="020405b4"/>
120       <field show="SACK permitted" size="2" pos="58" value="0402"/>
121       <field name="tcp.options.time_stamp" showname="TCP Time Stamp Option: True" hide="yes" size="10" pos="60" show="1" value="080a0a39e24b00000000"/>
122       <field show="Time stamp: tsval 171565643, tsecr 0" size="10" pos="60" value="080a0a39e24b00000000"/>
123       <field show="NOP" size="1" pos="70" value="01"/>
124       <field name="tcp.options.wscale" showname="TCP Window Scale Option: True" hide="yes" size="3" pos="71" show="1" value="030300"/>
125       <field name="tcp.options.wscale_val" showname="Window scale: 0 (multiply by 1)" size="3" pos="71" show="0" value="030300"/>
126     </field>
127   </proto>
128 </packet>
129  */

130
131 /**
132  * This class captures Ethernet frames using tethereal on a single layer-2 interface.
133  * The frames are parsed with SAX.
134  * @author Alexandre Fenyo
135  * @version $Id: Capture.java,v 1.13 2007/03/09 22:44:21 fenyo Exp $
136  */

137
138 public class Capture implements Runnable JavaDoc {
139   private static Log log = LogFactory.getLog(Capture.class);
140
141   final SAXReader reader = new SAXReader();
142
143   private final Config config;
144   private ExternalCommand cmd;
145   private CaptureManager manager;
146
147   private boolean forked = false;
148
149   private Thread JavaDoc capture_thread = null;
150
151   private boolean must_end = false;
152
153   /**
154    * Constructor.
155    * GUI thread.
156    * @param config configuration.
157    * @param manager capture manager this instance works for.
158    * @param device device this instance captures frames from.
159    * @param filter capture filter to apply.
160    */

161   // while debugging, sub processes may not die, so use the following DOS command line to terminate all running tethereal.exe :
162
// wmic process where Name='tethereal.exe' call terminate
163
public Capture(final Config config, final CaptureManager manager, final int device, final String JavaDoc filter) {
164     this.config = config;
165     this.manager = manager;
166     // to convert device to a string, we use the following expression : "" + device
167
// cmd = new ExternalCommand(new String [] { "tethereal", "-i", "" + device, "-T", "psml" }, true);
168
cmd = new ExternalCommand(new String JavaDoc [] { "tethereal", "-i", "" + device, "-T", "pdml", "-R", "\"" + filter + "\"" }, true);
169   }
170
171   /**
172    * Lists all available devices.
173    * @param none.
174    * @return list of device names.
175    * @throws InterruptedException exception.
176    */

177   // GUI thread
178
public static String JavaDoc [] listDevices() throws InterruptedException JavaDoc {
179     final String JavaDoc devices =
180       new ExternalCommand(new String JavaDoc [] { "tethereal", "-D" }, true).runStdout();
181     return devices == null ? null : devices.split("\n");
182   }
183
184   /**
185    * Starts the capture thread.
186    * @param none.
187    * @return void.
188    */

189   // GUI thread
190
public void createCaptureThread() {
191     capture_thread = new Thread JavaDoc(this, "Capture Thread");
192     capture_thread.start();
193   }
194
195   /**
196    * Stops the capture thread and waits for its end.
197    * @param none.
198    * @return void.
199    * @throws InterruptedException exception.
200    */

201   // if InterruptedException is thrown, the thread may not be ended
202
// GUI thread
203
public void end() throws InterruptedException JavaDoc {
204     must_end = true;
205     if (capture_thread != null) {
206       capture_thread.interrupt();
207     }
208
209     while (!forked) Thread.sleep(100);
210
211     try {
212       cmd.end();
213     } catch (final IOException ex) {
214       log.error("Exception", ex);
215     }
216
217     capture_thread.join();
218   }
219
220   /**
221    * Gives the next frame to the manager.
222    * @param packet next frame.
223    * @return void.
224    * @throws DocumentException SAX parse exception.
225    */

226   // must be called from the Capture thread since SAXReader is not synchronized
227
// Capture thread
228
private void handlePacket(final StringBuffer JavaDoc packet) throws DocumentException {
229     try {
230       final Document document = reader.read(new StringReader(packet.toString()));
231       manager.handlePacket(document);
232     } catch (final DocumentException ex) {
233       log.warn("packet: {" + packet + "}");
234       throw ex;
235     }
236   }
237
238   /**
239    * Reads tethereal standard output and extracts frames one by one.
240    * @param none.
241    * @return void.
242    */

243   // Capture thread
244
public void run() {
245     final StringBuffer JavaDoc packet = new StringBuffer JavaDoc();
246
247     try {
248       cmd.fork();
249       forked = true;
250
251       while (!config.isEnd() && !must_end) {
252         // on doit pouvoir optimiser en utilisant un StringBuffer pour str
253
final String JavaDoc str = cmd.readLineStdout();
254         if (str == null) break;
255         packet.append(str);
256         // log.debug("[" + str + "]");
257
// replaces invalid XML characters with ' '
258
for (int idx = 0; idx < packet.length(); idx++)
259           // http://www.w3.org/TR/REC-xml/#charsets
260
if (packet.charAt(idx) != 9 && packet.charAt(idx) != 10 &&
261               packet.charAt(idx) != 13 && packet.charAt(idx) < 32)
262             packet.setCharAt(idx, ' ');
263
264         if (str.contains("</packet>")) {
265           try {
266             handlePacket(packet);
267           } catch (final DocumentException ex) {
268             log.warn("Exception", ex);
269           }
270           packet.setLength(0);
271         }
272       }
273     } catch (final IOException ex) {
274       log.warn("Exception", ex);
275     } catch (final InterruptedException JavaDoc ex) {
276       // terminate the thread
277
} finally {
278       forked = true;
279     }
280   }
281 }
282
Popular Tags