Thursday, June 14, 2012

Traceroute using jpcap java libraray

Hi All,
Recently I came across a problem to develop a network traceroute application in JAVA. I tried Jpcap example code but it does not seems working in Window environment giving Destination unreachable(port unreachable) every time even though the normal traceroute through window command prompt is working fine. So I modified the code to make it working. Please change the IPs and interface index number as per your requirement.

How traceroute works:-

First we send a echo request packet with TTL value=1, the destination if reachable will reply with TTL expired. Capture this packet, this will be our first hop. Now increase the hop limit(TTL) by one and resend the packet. Capture the reply packet and so on till we get the echo reply packet from our actual destination.

hopes it will help you.

For any further query  contact me at lkpatel123 at the rate of gmail.com


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jpcaputil;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.URL;
import java.util.Arrays;

import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import jpcap.NetworkInterface;
import jpcap.NetworkInterfaceAddress;
import jpcap.packet.EthernetPacket;
import jpcap.packet.ICMPPacket;
import jpcap.packet.IPPacket;
import jpcap.packet.Packet;

public class Traceroute {
    public static void main(String[] args) throws Exception{
        /*if(args.length<2){
            System.out.println("Usage: java Traceroute ");
            System.exit(0);
        }*/
           
               InetAddress srcIP=InetAddress.getByName("10.21.34.233");
               InetAddress dstIP=InetAddress.getByName("172.21.3.1");
               int ifIndex=2; //device interface index
       
        //initialize Jpcap
        NetworkInterface device=JpcapCaptor.getDeviceList()[ifIndex];
        JpcapCaptor captor=JpcapCaptor.openDevice(device,2000,false,5000);
       
        /*for(NetworkInterfaceAddress addr:device.addresses)
            if(addr.address instanceof Inet4Address){
                thisIP=addr.address;
                break;
            }
        */
               
              
        //obtain MAC address of the default gateway
        InetAddress pingAddr=InetAddress.getByName("google.co.in");
        captor.setFilter("tcp and dst host "+pingAddr.getHostAddress(),true);
        byte[] gwmac=null;
        while(true){
            new URL("http://google.co.in").openStream().close();
            Packet ping=captor.getPacket();
            if(ping==null){
                System.out.println("cannot obtain MAC address of default gateway.");
                System.exit(-1);
            }else if(Arrays.equals(((EthernetPacket)ping.datalink).dst_mac,device.mac_address))
                    continue;
            gwmac=((EthernetPacket)ping.datalink).dst_mac;
                      break;
        }
       
        //create ICMP packet
        ICMPPacket icmp=new ICMPPacket();
        icmp.type=ICMPPacket.ICMP_ECHO;
        icmp.seq=100;
        icmp.id=0x0300;
        icmp.setIPv4Parameter(0,false,false,false,0,false,false,false,0,0,0,IPPacket.IPPROTO_ICMP,
                srcIP,dstIP);
                byte[] myData=new byte[64];
                for(int i=0;i<64;i++)
                    myData[i]=(byte)00;
        icmp.data=myData;
       
        EthernetPacket ether=new EthernetPacket();
        ether.frametype=EthernetPacket.ETHERTYPE_IP;
        ether.src_mac=device.mac_address;
        ether.dst_mac=gwmac;
        icmp.datalink=ether;
       
        captor.setFilter("icmp and dst host "+srcIP.getHostAddress(),true);
        JpcapSender sender=captor.getJpcapSenderInstance();
        //JpcapSender sender=JpcapSender.openDevice(device);
                icmp.hop_limit=1;
        sender.sendPacket(icmp);
        while(true){
            ICMPPacket p=(ICMPPacket) captor.getPacket();
            //System.out.println("received "+p);
            if(p==null){
                System.out.println("Timeout");
            }else if(p.type==ICMPPacket.ICMP_TIMXCEED){
                                //System.out.println( "Got time exceeded "+  icmp.hop_limit+": "+p.src_ip);               
               
                System.out.println(icmp.hop_limit+": "+p.src_ip);
                icmp.hop_limit++;
            }else if(p.type==ICMPPacket.ICMP_UNREACH){
                                //System.out.println("Got icmp  unreach reply "+  icmp.hop_limit+": "+p.src_ip);
               
                System.out.println(icmp.hop_limit+": "+p.src_ip);
                                sender.close();
                System.exit(0);
            }else if(p.type==ICMPPacket.ICMP_ECHOREPLY){
                                //System.out.println("Got echo  reply "+ icmp.hop_limit+": "+p.src_ip);                             
                System.out.println(icmp.hop_limit+": "+p.src_ip);
                                sender.close();
                System.exit(0);
                                 }
                        else if (p.type==ICMPPacket.ICMP_REDIRECT_TOSHOST){ 
                             
                               // System.out.println("Got redirect reply "+ icmp.hop_limit+": "+p.src_ip);
                                sender.close();
                                System.exit(0);
            }else continue;
                      //  System.out.println("in while loop, about to send " + icmp.toString() + " with hoplimit of " + icmp.hop_limit); 
                  
            sender.sendPacket(icmp);
        }
    }
}


1 comment:

  1. Hi Lalit, I am getting javax.naming.NoInitialContextException: when using jpCap..any hep?

    ReplyDelete