24 import sun.security.util.HexDumpEncoder; |
24 import sun.security.util.HexDumpEncoder; |
25 |
25 |
26 import java.io.PrintStream; |
26 import java.io.PrintStream; |
27 import java.net.DatagramPacket; |
27 import java.net.DatagramPacket; |
28 import java.net.DatagramSocket; |
28 import java.net.DatagramSocket; |
|
29 import java.net.InetAddress; |
29 import java.net.InetSocketAddress; |
30 import java.net.InetSocketAddress; |
30 import java.net.SocketAddress; |
31 import java.net.SocketAddress; |
31 import java.net.SocketException; |
32 import java.net.SocketException; |
32 import java.nio.ByteBuffer; |
33 import java.nio.ByteBuffer; |
33 import java.util.Arrays; |
34 import java.util.Arrays; |
44 * |
45 * |
45 * xxxx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ................ |
46 * xxxx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ................ |
46 * |
47 * |
47 * Typically, the capture file data will be used by DNSServer for playback |
48 * Typically, the capture file data will be used by DNSServer for playback |
48 */ |
49 */ |
49 public class DNSTracer implements Runnable { |
50 public class DNSTracer extends Thread implements Server { |
50 public static final int DNS_DEFAULT_PORT = 53; |
51 public static final int DNS_DEFAULT_PORT = 53; |
51 public static final int DNS_PACKET_SIZE = 512; |
52 public static final int DNS_PACKET_SIZE = 512; |
52 static HexDumpEncoder encoder = new HexDumpEncoder(); |
53 static HexDumpEncoder encoder = new HexDumpEncoder(); |
53 |
54 |
54 private DatagramSocket inSocket; |
55 private DatagramSocket inSocket; |
55 private SocketAddress dnsServerAddress; |
56 private SocketAddress dnsServerAddress; |
56 private ByteBuffer reqBuffer = ByteBuffer.allocate(DNS_PACKET_SIZE); |
57 private ByteBuffer reqBuffer = ByteBuffer.allocate(DNS_PACKET_SIZE); |
57 private ByteBuffer resBuffer = ByteBuffer.allocate(DNS_PACKET_SIZE); |
58 private ByteBuffer resBuffer = ByteBuffer.allocate(DNS_PACKET_SIZE); |
58 private PrintStream out = null; |
59 private PrintStream out = null; |
|
60 private volatile boolean isRunning; |
59 |
61 |
60 public DNSTracer(DatagramSocket socket, String dnsHostname) { |
62 public DNSTracer(String dnsHostname) throws SocketException { |
61 this(socket, dnsHostname, DNS_DEFAULT_PORT); |
63 this(dnsHostname, DNS_DEFAULT_PORT); |
62 } |
64 } |
63 |
65 |
64 public DNSTracer(DatagramSocket socket, PrintStream outStream, |
66 public DNSTracer(PrintStream outStream, String dnsHostname) |
65 String dnsHostname) { |
67 throws SocketException { |
66 this(socket, outStream, dnsHostname, DNS_DEFAULT_PORT); |
68 this(outStream, dnsHostname, DNS_DEFAULT_PORT); |
67 } |
69 } |
68 |
70 |
69 public DNSTracer(DatagramSocket socket, String dnsHostname, int dnsPort) { |
71 public DNSTracer(String dnsHostname, int dnsPort) throws SocketException { |
70 this(socket, System.out, dnsHostname, dnsPort); |
72 this(System.out, dnsHostname, dnsPort); |
71 } |
73 } |
72 |
74 |
73 public DNSTracer(DatagramSocket socket, PrintStream outStream, |
75 public DNSTracer(PrintStream outStream, String dnsHostname, int dnsPort) |
74 String dnsHostname, int dnsPort) { |
76 throws SocketException { |
75 inSocket = socket; |
77 inSocket = new DatagramSocket(0, InetAddress.getLoopbackAddress()); |
76 out = outStream; |
78 out = outStream; |
77 dnsServerAddress = new InetSocketAddress(dnsHostname, dnsPort); |
79 dnsServerAddress = new InetSocketAddress(dnsHostname, dnsPort); |
78 } |
80 } |
79 |
81 |
80 public void run() { |
82 public void run() { |
|
83 isRunning = true; |
81 System.out.println( |
84 System.out.println( |
82 "DNSTracer: listening on port " + inSocket.getLocalPort()); |
85 "DNSTracer: listening on port " + inSocket.getLocalPort()); |
83 |
86 |
84 System.out.println("DNSTracer: will forward request to server " |
87 System.out.println("DNSTracer: will forward request to server " |
85 + dnsServerAddress); |
88 + dnsServerAddress); |
114 |
117 |
115 inSocket.send(new DatagramPacket(resPacket.getData(), |
118 inSocket.send(new DatagramPacket(resPacket.getData(), |
116 resPacket.getLength(), reqPacket.getSocketAddress())); |
119 resPacket.getLength(), reqPacket.getSocketAddress())); |
117 } |
120 } |
118 } catch (SocketException se) { |
121 } catch (SocketException se) { |
119 if (inSocket.isClosed()) { |
122 if (!isRunning) { |
120 out.flush(); |
123 out.flush(); |
121 System.out.println("DNSTracer: Exit"); |
124 System.out.println("DNSTracer: Exit"); |
122 } else { |
125 } else { |
123 se.printStackTrace(); |
126 se.printStackTrace(); |
124 } |
127 } |
125 } catch (Exception e) { |
128 } catch (Exception e) { |
126 e.printStackTrace(); |
129 e.printStackTrace(); |
127 } |
130 } |
128 } |
131 } |
129 |
132 |
|
133 @Override public void stopServer() { |
|
134 isRunning = false; |
|
135 if (inSocket != null) { |
|
136 try { |
|
137 inSocket.close(); |
|
138 } catch (Exception e) { |
|
139 // ignore |
|
140 } |
|
141 } |
|
142 } |
|
143 |
|
144 @Override public int getPort() { |
|
145 if (inSocket != null) { |
|
146 return inSocket.getLocalPort(); |
|
147 } else { |
|
148 return -1; |
|
149 } |
|
150 } |
130 } |
151 } |