|
A veces para analizar protocolos de comunicaciones o para sobrepasar algun firewall, siembre es bueno contar con un tunnel.
Estos son dos tunneles hecho en java muy pequeños. Uno sirve para mostrar los datos que se transfieren a traves de la red usando un canvas de AWT para mostrar los resultados en hexadecimal. El otro es para realizar un tunnel sin otros extras.
Este codigo realiza las siguientes acciones:
- Levanta un ServerSocket
- Por cada cliente crea una tarea ConectionThread
- cada ConectionThread crea una ventana de información HexCanvas
- El proceso termina cuando se recibe el ultimo byte.
- El canvas con la informacion hexadecimal queda abierto luego de terminar el flujo de informacion
Listado 1: Proxy4.java
package net.proxy;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Proxy4 {
int listenPort;
String realAdress;
int realPort;
public Proxy4(int p, String s, int sp) {
listenPort = p;
realAdress = s;
realPort = sp;
}
public void start() {
ServerSocket mainSocket;
int n = 0;
try {
mainSocket = new ServerSocket(listenPort);
System.out.println("Listenning...");
while (true) {
Socket client = mainSocket.accept();
n++;
Socket server = new Socket(realAdress, realPort);
ConectionThread ct = new ConectionThread(client, server, n);
ct.start();
}
} catch (Exception e) {
}
}
public static void main(String args[]) {
if (args.length < 2) {
System.out.println(
"java Proxy4 listenPort realAdress [realPort(=listenPort)]");
return;
}
int listenPort, realPort;
listenPort = Integer.parseInt(args[0]);
if (args.length == 3)
realPort = Integer.parseInt(args[2]);
else
realPort = listenPort;
Proxy4 proxy = new Proxy4(listenPort, args[1], realPort);
proxy.start();
}
static class ConectionThread extends Thread implements ActionListener {
Socket client, server;
Frame f;
HexCanvas hexView;
boolean active = true;
int num = 0;
public ConectionThread(Socket c, Socket s, int n) {
client = c;
server = s;
num = n;
}
public void actionPerformed(ActionEvent ev) {
String c = ev.getActionCommand();
if (c.equals("Clear")) {
hexView.clear();
} else if (c.equals("Close"))
active = false;
}
private void createFrame() {
f = new Frame("" + num);
f.setLayout(new BorderLayout());
Panel mainPanel = new Panel();
hexView = new HexCanvas();
f.add("Center", hexView);
Panel buttonPanel = new Panel();
buttonPanel.setLayout(new FlowLayout());
Button b;
b = new Button("Clear");
b.addActionListener(this);
buttonPanel.add(b);
b = new Button("Close");
b.addActionListener(this);
buttonPanel.add(b);
f.add("South", buttonPanel);
f.pack();
}
public void run() {
createFrame();
f.setVisible(true);
try {
trace();
} catch (IOException e) {
System.out.println("Run IOException:" + e.toString());
}
f.setVisible(false);
}
private void trace() throws IOException {
InputStream fromClient = client.getInputStream();
OutputStream toClient = client.getOutputStream();
InputStream fromServer = server.getInputStream();
OutputStream toServer = server.getOutputStream();
byte buffer[] = new byte[1024 * 64];
int nread;
try {
while (active) {
if (fromClient.available() > 0) {
nread = fromClient.read(buffer);
toServer.write(buffer, 0, nread);
toServer.flush();
hexView.addData(buffer, nread, "fromClient");
}
if (fromServer.available() > 0) {
nread = fromServer.read(buffer);
toClient.write(buffer, 0, nread);
toClient.flush();
hexView.addData(buffer, nread, "fromServer:");
}
}
} catch (Exception e) {
System.out.println("Trace Exception:" + e.toString());
}
client.close();
server.close();
}
}
static class HexCanvas extends java.awt.TextArea {
StringBuffer sb = new StringBuffer(100);
public HexCanvas() {
super();
setFont(new Font("monospaced", 8, Font.PLAIN));
}
public void clear() {
setText("");
}
public void addData(byte b[], int bsize, String sender) {
append("n" + sender + ":n");
int p = 0;
while (p <= (bsize - 16)) {
append(getHexLine(b, p, 16));
p += 16;
}
int lastidx = bsize - p;
if (lastidx > 0) {
append(getHexLine(b, p, lastidx));
}
}
public String getHexLine(byte b[], int pos, int count) {
sb.setLength(0);
for (int i = 0; i < 16; i++) {
if (i < count)
sb.append(toHex(b[pos + i]));
else
sb.append(" ");
sb.append(" ");
}
sb.append(" ");
for (int i = pos; i < pos + count; i++) {
if (b[i] > ' ')
sb.append((char) b[i]);
else
sb.append(".");
}
sb.append("n");
return sb.toString();
}
String toHex(byte b) {
int a = b;
if (a < 0)
a = 256 + a;
String chars = "0123456789ABCDEF";
int i = a / 16;
int j = a % 16;
String r = "" + chars.charAt(i);
r += chars.charAt(j);
return r;
}
}
}
LIstado 2: Proxy2.java (sin interfaz)
package net.proxy;
import java.net.*;
import java.io.*;
class ThreadCliente2 extends Thread {
InputStream is;
OutputStream os;
char pantalla;
public ThreadCliente2(InputStream i, OutputStream o, char p) {
is = i;
os = o;
pantalla = p;
}
public void run(){
try {
int c;
char ch;
while(true){
if ((c=is.read())>=0) {
System.out.print(pantalla);
System.out.print((char)c);
os.write(c);
os.flush();
}
}
} catch( Exception e){}
}
}
public class Proxy2 {
private ServerSocket server;
private int portnum;
private String realServer;
private int realPort;
protected void administra(Socket skt) throws Exception {
Socket clsock, dbsock;
InputStream dbin ;
OutputStream dbout ;
InputStream clin ;
OutputStream clout ;
clsock = skt;
clin = clsock.getInputStream ();
clout = clsock.getOutputStream();
dbsock = new Socket (realServer,realPort);
dbin = dbsock.getInputStream ();
dbout = dbsock.getOutputStream();
new ThreadCliente2 ( clin, dbout, 'C' ).start();
new ThreadCliente2 ( dbin, clout, 'S' ).start();
}
public Proxy2 (int port, String servidor, int port2) {
portnum = port;
realServer = servidor;
realPort = port2;
try {
server = new ServerSocket ( portnum );
while (true){
Socket cliente = server.accept();
administra(cliente);
}
}
catch (Exception e) {}
}
public static void main (String args[]) {
if (args.length==3) {
int port1 = Integer.parseInt(args[0]);
int port2 = Integer.parseInt(args[2]);
new Proxy2(port1, args[1], port2);
}
else
System.err.println("java Proxy2 <port> <server addr> <server port>");
}
}
|