1 11 package org.eclipse.jdi.internal.spy; 12 13 14 import java.io.BufferedInputStream ; 15 import java.io.BufferedOutputStream ; 16 import java.io.DataInputStream ; 17 import java.io.DataOutputStream ; 18 import java.io.EOFException ; 19 import java.io.File ; 20 import java.io.FileNotFoundException ; 21 import java.io.FileOutputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.io.OutputStream ; 25 import java.net.InetAddress ; 26 import java.net.ServerSocket ; 27 import java.net.Socket ; 28 import java.net.SocketException ; 29 import com.ibm.icu.text.MessageFormat; 30 import java.util.HashMap ; 31 import java.util.Map ; 32 33 47 public class TcpipSpy extends Thread { 48 49 private static final byte[] handshakeBytes= "JDWP-Handshake".getBytes(); private boolean fVMtoDebugger; 51 private DataInputStream fDataIn; 52 private DataOutputStream fDataOut; 53 54 private static VerbosePacketStream out= new VerbosePacketStream(System.out); 55 private static Map fPackets= new HashMap (); 56 57 private static int fFieldIDSize; 58 private static int fMethodIDSize; 59 private static int fObjectIDSize; 60 private static int fReferenceTypeIDSize; 61 private static int fFrameIDSize; 62 private static boolean fHasSizes; 63 64 public TcpipSpy(boolean VMtoDebugger, InputStream in, OutputStream out) { 65 fVMtoDebugger= VMtoDebugger; 66 fDataIn= new DataInputStream (new BufferedInputStream (in)); 67 fDataOut= new DataOutputStream (new BufferedOutputStream (out)); 68 fHasSizes= false; 69 } 70 71 public static void main(String [] args) { 72 int inPort= 0; 73 String serverHost= null; 74 int outPort= 0; 75 String outputFile= null; 76 try { 77 inPort= Integer.parseInt(args[0]); 78 serverHost= args[1]; 79 outPort= Integer.parseInt(args[2]); 80 if (args.length > 3) { 81 outputFile= args[3]; 82 } 83 } catch (Exception e) { 84 out.println("usage: TcpipSpy <client port> <server host> <server port> [<output file>]"); System.exit(-1); 86 } 87 88 if (outputFile != null) { 89 File file= new File (outputFile); 90 out.println(MessageFormat.format("Writing output to {0}", new String [] {file.getAbsolutePath()})); try { 92 out= new VerbosePacketStream(new BufferedOutputStream (new FileOutputStream (file))); 93 } catch (FileNotFoundException e) { 94 out.println(MessageFormat.format("Could not open {0}. Using stdout instead", new String [] {file.getAbsolutePath()})); } 96 } 97 out.println(); 98 try { 99 ServerSocket serverSock= new ServerSocket (inPort); 100 Socket inSock= serverSock.accept(); 101 Socket outSock= new Socket (InetAddress.getByName(serverHost), outPort); 102 new TcpipSpy(false, inSock.getInputStream(), outSock.getOutputStream()).start(); 103 new TcpipSpy(true, outSock.getInputStream(), inSock.getOutputStream()).start(); 104 } catch (Exception e) { 105 out.println(e); 106 } 107 } 108 109 public void run() { 110 try { 111 int handshakeLength; 113 114 handshakeLength= handshakeBytes.length; 115 while (handshakeLength-- > 0) { 116 int b= fDataIn.read(); 117 fDataOut.write(b); 118 } 119 fDataOut.flush(); 120 121 while (true) { 123 JdwpPacket p= JdwpPacket.read(fDataIn); 124 if (!(fVMtoDebugger && (p.getFlags() & JdwpPacket.FLAG_REPLY_PACKET) == 0)) { 127 store(p); 128 } 129 out.print(p, fVMtoDebugger); 130 out.flush(); 131 p.write(fDataOut); 132 fDataOut.flush(); 133 } 134 } catch (EOFException e) { 135 } catch (SocketException e) { 136 } catch (IOException e) { 137 out.println(MessageFormat.format("Caught exception: {0}", new String [] {e.toString()})); e.printStackTrace(out); 139 } finally { 140 try { 141 fDataIn.close(); 142 fDataOut.close(); 143 } catch (IOException e) { 144 } 145 out.flush(); 146 } 147 } 148 149 public static JdwpCommandPacket getCommand(int id) { 150 JdwpConversation conversation= (JdwpConversation) fPackets.get(new Integer (id)); 151 if (conversation != null) 152 return conversation.getCommand(); 153 return null; 154 } 155 156 protected static void store(JdwpPacket packet) { 157 int id= packet.getId(); 158 JdwpConversation conversation= (JdwpConversation) fPackets.get(new Integer (id)); 159 if (conversation == null) { 160 conversation= new JdwpConversation(id); 161 fPackets.put(new Integer (id), conversation); 162 } 163 164 if ((packet.getFlags() & JdwpPacket.FLAG_REPLY_PACKET) != 0) { 165 conversation.setReply((JdwpReplyPacket) packet); 166 } else { 167 conversation.setCommand((JdwpCommandPacket) packet); 168 } 169 } 170 171 public static int getCommand(JdwpPacket packet) throws UnableToParseDataException { 172 JdwpCommandPacket command= null; 173 if (packet instanceof JdwpCommandPacket) { 174 command= (JdwpCommandPacket) packet; 175 } else { 176 command= getCommand(packet.getId()); 177 if (command == null) { 178 throw new UnableToParseDataException("This packet is marked as reply, but there is no command with the same id.", null); } 180 } 181 return command.getCommand(); 182 } 183 184 public static boolean hasSizes() { 185 return fHasSizes; 186 } 187 188 public static void setHasSizes(boolean value) { 189 fHasSizes= value; 190 } 191 192 public static void setFieldIDSize(int fieldIDSize) { 193 fFieldIDSize= fieldIDSize; 194 } 195 196 public static int getFieldIDSize() { 197 return fFieldIDSize; 198 } 199 200 public static void setMethodIDSize(int methodIDSize) { 201 fMethodIDSize= methodIDSize; 202 } 203 204 public static int getMethodIDSize() { 205 return fMethodIDSize; 206 } 207 208 public static void setObjectIDSize(int objectIDSize) { 209 fObjectIDSize= objectIDSize; 210 } 211 212 public static int getObjectIDSize() { 213 return fObjectIDSize; 214 } 215 216 public static void setReferenceTypeIDSize(int referenceTypeIDSize) { 217 fReferenceTypeIDSize= referenceTypeIDSize; 218 } 219 220 public static int getReferenceTypeIDSize() { 221 return fReferenceTypeIDSize; 222 } 223 224 public static void setFrameIDSize(int frameIDSize) { 225 fFrameIDSize= frameIDSize; 226 } 227 228 public static int getFrameIDSize() { 229 return fFrameIDSize; 230 } 231 } 232 | Popular Tags |