3

I need to create a program that receives HTTP request and forwards those requests to the web servers.

Diagram http://img269.imageshack.us/img269/1862/h98trsly.jpg

I have successfully made this using only Java Sockets but the client needed the program to be implemented in Jpcap. I'd like to know if this is possible and what literature I should be reading for this project.

This is what I have now by stitching together pieces from the Jpcap tutorial:

import java.net.InetAddress;
import java.io.*;
import jpcap.*;
import jpcap.packet.*;


public class Router {
    public static void main(String args[]) {
        //Obtain the list of network interfaces
        NetworkInterface[] devices = JpcapCaptor.getDeviceList();

        //for each network interface
        for (int i = 0; i < devices.length; i++) {
            //print out its name and description
            System.out.println(i+": "+devices[i].name + "(" + devices[i].description+")");

            //print out its datalink name and description
            System.out.println(" datalink: "+devices[i].datalink_name + "(" + devices[i].datalink_description+")");

            //print out its MAC address
            System.out.print(" MAC address:");
            for (byte b : devices[i].mac_address)
                System.out.print(Integer.toHexString(b&0xff) + ":");
            System.out.println();

            //print out its IP address, subnet mask and broadcast address
            for (NetworkInterfaceAddress a : devices[i].addresses)
                System.out.println(" address:"+a.address + " " + a.subnet + " "+ a.broadcast);
        }

        int index = 1;  // set index of the interface that you want to open.

        //Open an interface with openDevice(NetworkInterface intrface, int snaplen, boolean promics, int to_ms)
        JpcapCaptor captor = null;
        try {
            captor = JpcapCaptor.openDevice(devices[index], 65535, false, 20);
            captor.setFilter("port 80 and host 192.168.56.1", true);
        } catch(java.io.IOException e) {
            System.err.println(e);
        }

        //call processPacket() to let Jpcap call PacketPrinter.receivePacket() for every packet capture.
        captor.loopPacket(-1,new PacketPrinter());

        captor.close();
    }
}

class PacketPrinter implements PacketReceiver {
    //this method is called every time Jpcap captures a packet
    public void receivePacket(Packet p) {
        JpcapSender sender = null;
        try {
            NetworkInterface[] devices = JpcapCaptor.getDeviceList();
            sender = JpcapSender.openDevice(devices[1]);
        } catch(IOException e) {
            System.err.println(e);
        }


        IPPacket packet = (IPPacket)p;

        try {
            // IP Address of machine sending HTTP requests (the client)
            // It's still on the same LAN as the servers for testing purposes.
            packet.dst_ip = InetAddress.getByName("192.168.56.2");
        } catch(java.net.UnknownHostException e) {
            System.err.println(e);
        }

        //create an Ethernet packet (frame)
        EthernetPacket ether=new EthernetPacket();
        //set frame type as IP
        ether.frametype=EthernetPacket.ETHERTYPE_IP;
        //set source and destination MAC addresses

        // MAC Address of machine running reverse proxy server
        ether.src_mac = new MacAddress("08:00:27:00:9C:80").getAddress();
        // MAC Address of machine running web server
        ether.dst_mac = new MacAddress("08:00:27:C7:D2:4C").getAddress();

        //set the datalink frame of the packet as ether
        packet.datalink=ether;

        //send the packet
        sender.sendPacket(packet);

        sender.close();

        //just print out a captured packet
        System.out.println(packet);
    }
}

Any help would be greatly appreciated. Thank you.

  • Presuming the jpcap restriction, are we talking about doing a wireshark-style http trace in realtime, snarfing up those packets, making a request to the proper place, and then redirecting that response back to the client as if it was the response from its own request? Either I really don't understand packet capture, or that's a daunting task. Isn't this sort of thing in the realm of Cisco's Layer7 stuff on their routers? – ShabbyDoo Mar 22 '10 at 00:53
  • Yes, that's correct ShabbyDoo. – Ramon Marco L. Navarro Mar 22 '10 at 16:38

2 Answers2

1

Why? What are his reasons? Does he really want to pay ten times the cost for the same thing you've already done?

You don't need Jpcap to implement HTTP proxies. It can be done entirely within java.net or java.nio.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Because they wrote on their thesis that they'll use Jpcap. :)) – Ramon Marco L. Navarro Feb 15 '10 at 14:18
  • @EJB. Agree and wonder what the benefit of writing such a thing would be given all the open source stuff out there. Is this perhaps a homework assignment? Is the "client" some student who doesn't want to do his own project? – ShabbyDoo Mar 22 '10 at 00:52
  • I'm sorry. I forgot to check this answer. I'm finished with this project and just used socket programming. Way easier and I don't see the benefit of doing it "raw" in this case. – Ramon Marco L. Navarro Mar 22 '10 at 16:40
1

I don't think you can make this happen, at least on a Windows box. Jpcap is just a wrapper for Winpcap, and this underlying mechanism can not drop observed packets:

http://www.mirrorservice.org/sites/ftp.wiretapped.net/pub/security/packet-capture/winpcap/misc/faq.htm#Q-17

So, I don't see how you can build a reverse proxy "on the wire." Wouldn't you have to do the following:

  1. Observe an incoming HTTP request by piecing together packets in real-time AND dropping them from being received by the intended host.

  2. Make the alternate HTTP request based on whatever proxy rules you are implementing.

  3. Grab the response from your request and push out packets on the wire which fake a response from the original host?

Since you can't drop the inbound packets, won't the intended host attempt to handle the request and throw packets of its own onto the wire in response? There's probably even more that I don't know about as I'm no networking expert. This question just made me curious about what would be possible using such a "shim".

ShabbyDoo
  • 1,256
  • 1
  • 11
  • 20
  • Before I went the socket programming route, I really did try implementing this using JPCap. What I did was: I sniffed the exchange of nginx on reverse proxy mode with a client computer and another computer running webserver. Using the data from the "experiment", I tried to do it using JPCap instead of nginx, but got stuck on how the client computer automatically selects an available port from where the other computer could connect. I'm sure that's not just the problem that I would encounter if I did continue going the JPCap route. – Ramon Marco L. Navarro Mar 22 '10 at 16:46
  • Also, IIRC, nginx didn't drop any packets coming from the client computer. I might be wrong though. – Ramon Marco L. Navarro Mar 22 '10 at 16:47
  • A reverse proxy doesn't have to drop packets. You are speaking of a firewall. Not the same thing. A reverse proxy is perceived by the client as the actual server. He hasn't said anything about 'on the wire'. – user207421 May 29 '12 at 23:16