Menu

Tutorial 3 Example 1

Bernardo Bulgarelli Labronici

Example 1

Set filter to capture only specific type of of packets. Set maximun size capture size and thread truncated packets (packets bigger than maximum capture size)

        //We will set an capture filter.
        //So the maximum packets size capture will be 100 bytes in this case.
        //You can set a ping to an Address with size bigger that this 100 bytes in order 
        //to see the effects of frame truncation
        //e.g ping 8.8.8.8 -l 150 -t
        //ping to google DNS with data size of 150 bytes (this will guarantee that the 
        //frames are truncated)
        Capture cap = new Capture(100);


        try {


            //Let's get all the devices available in the machine for pcap
            //If any error occurs it will be throw as an NetworkDeviceException
            List<NetworkDevice> networkDevices = cap.getNetworkDevices();

            //Assuming the first device is a valid device for capture.
            //we can use it.
            //Print basic info of device
            //We will connect to this device to sniff packets from
            NetworkDevice device = networkDevices.get(0);

            System.out.println();
            System.out.println("  Pcap Device Name: " + device.getName());
            System.out.println("Device Description: " + device.getDescription());
            System.out.println();

            //Add a new adapter to the Capture Listener.
            cap.addListener(new CaptureAdapter(){

                //This function is called by Sniffer4J.Dll for each new received Frame
                @Override
                public void capture(Frame frame) {


                    System.out.println();
                    //Show if the frame has truncated
                    System.out.println("truncated: " + frame.isTruncated());

                    //Since the filter bellow are set to accept only arp and icmp packets
                    //Only this packets should be presented

                    //Find Arp
                    ArpPdu arp = frame.getPduByClass(ArpPdu.class);
                    if(arp != null){
                        System.out.println("I found a Arp packet. Arp operation is: "
                                + arp.getOperation().getName());
                        System.out.println(arp.toString());
                        return;
                    }

                    //Find IcmpV4
                    IcmpV4Pdu icmpV4 = frame.getPduByClass(IcmpV4Pdu.class);
                    if(icmpV4 != null){

                        System.out.println("I found a Icmp packet. "
                                + icmpV4.getType().getName());

                        //If it is a echo reply or request
                        //Show it
                        if(icmpV4.getType() == IcmpV4Protocol.ECHOREPLY ||
                                icmpV4.getType() == IcmpV4Protocol.ECHOREQUEST ){
                            IcmpDataEcho echo = (IcmpDataEcho)icmpV4.getIcmpData();
                            System.out.println("Icmp Echo. "
                                    + ArrayHelper.toString(echo.getEchoData()));
                        }
                        return;
                    }

                    //Find IcmpV6
                    IcmpV6Pdu icmpV6 = frame.getPduByClass(IcmpV6Pdu.class);
                    if(icmpV6 != null){

                        System.out.println("I found a IcmpV6 packet. "
                                + icmpV6.getType().getName());

                        return;
                    }                   

                    //Should NEVER goes up to here unless it is truncate
                    //Because if the packet truncated, this means that Sniffer4J did not parsed Icmp
                    //message properly, and no IcmpPdu were ever found (it was returned as an RawPdu)
                    Pdu pdu = frame.getFirstPdu();
                    EthernetPdu eth = (EthernetPdu)pdu;
                    System.err.println("This packet should not be here, if it is not truncated" + eth.getEtherType().getName());


                    //If we have Raw Pdu, or the Frame truncate, or there is an unknown protocol
                    RawPdu raw = frame.getPduByClass(RawPdu.class);
                    if(raw != null){
                        System.err.println("There is a Raw packet... or a packet truncate, or Sniffer4J do not know this protocol");
                        System.err.println(ArrayHelper.toHexString(raw.getData().array()));

                }

            }); 


            //Connect to device (ignore timeout, show packets as they arrive)
            cap.connect(device, -1);

            //Set filter for this capture
            //Only arp and Icmp packets are accepted by pcap lib
            cap.setFilters("icmp || arp");


            //Start the Capture and block until the 20 packet has been received and processed
            //by CaptureAdapter
            cap.CaptureFramesLoop(20);

            //Close the Capture Device
            cap.close();

        }catch(NetworkDeviceException e){

            System.err.println("Error in the cap.getNetworkDevices();");
            e.printStackTrace();

        }catch(CaptureS4JException e){

            System.err.println("Error in the connection.");
            e.printStackTrace();

        }catch (JNIException e) {

            System.err.println("Error With the Dll");
            e.printStackTrace();
        } catch (NotSupportedDatalinkS4JException e) {

            System.err.println("Datalink not Supported, only Ethernet");
            e.printStackTrace();
        }

First we will set the maximum size of the capture Frame. This is done during the instantiation of the Capture Class.
It’s worth to mention pcap libs ONLY take those parameters into account if a filter is set, even if it is an empty filter, but a filter must be set.

Capture cap = new Capture(100);

In this example whe set the than maxFrameLength to be 100 byte in size

Whenever a packet is bigger than maxFrameLength pcap will only return up to maxFrameLength and the frame is truncate. Since Sniffer4J will not be able to parse the truncate frame those bytes will be returned in a special Pdu called RawPadu

br.com.sniffer4j.packets.pdu.RawPdu

RawPdu have a single field that is a byte[] with all the bytes that could not be parsed to a Pdu (whether because the Frame truncated, or because Sniffer4J do not know this type of Pdu yet).

Finally before the Capture, the filter are set with the command:

cap.setFilters("icmp || arp");

In this example, pcap lib will only return icmp or arp packets. A great resource about filters pcap sintax can be found at http://www.winpcap.org/docs/docs_40_2/html/group__language.html

Since arp packets are small, and Sniffer4J can parse them properly you probably won’t see any truncated arp packet.
But you can for an Icmp packet bigger them the 100 bytes size defined by the maxFrameLength
Just issue a ping to a known up address with data content bigger than 100 bytes, e.g

ping 8.8.8.8 -l 150 -t

Will fire infinity amount of Icmp Echo request messages for the Google DNS server (which is most likely to be up) with payload length of 150 bytes.
This should cause some RawPdu to appears due to truncation.


Related

Wiki: Tutorial

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.