Menu

Tutorial 4 Example 1

Bernardo Bulgarelli Labronici

Example 1

Before we start a moment of awareness…

WARNING

Be extra careful when inject synthetic packets to your network. Make sure you known what you are doing, or that you are using a completely separate network to do so.
Conflict of IP and Mac address may cause some of you servers to stop working or present odd behavior.
BE WARNED!!

Shows how to create custom packets and send them to the network.

        //Create a connection to pcap
        //For now let's ignore maxFrameLength, since it depends on the creation
        //of filter to work.
        Capture cap = new Capture(0);


        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());


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

            Address destinationMac = Address.getMacAddress(
                    new byte[]{(byte)0,(byte)1,(byte)2,(byte)3,(byte)4,(byte)5});

            Address sourceMac = Address.getMacAddress(
                    new byte[]{(byte)0,(byte)1,(byte)2,(byte)3,(byte)6,(byte)5});

            System.out.println(destinationMac.isMacAddress());

            //Ethernet Pdu
            //Mac destination 0:1:2:3:4:5
            //Mac Source 0:1:2:3:4:6:5
            //Protocol type Ipx
            EthernetPdu eth = new EthernetPdu(destinationMac,sourceMac, EtherTypeProtocol.ARP);


            //This is a completely bogus Arp packet, but yet completely VALID!!
            //Sniffer your network with Wireshark and you will se the result
            //The packet is not corrupt (although Protocol Address that is usually 
            //a 4 byte Ip address, is a 6 byte Mac address)
            ArpPdu arp = new ArpPdu(destinationMac,destinationMac,destinationMac,
                    destinationMac,EtherTypeProtocol.IPX,ArpProtocol.ARP_OP_REQ_CODE);

            //Set Arp as the next Pdu of Ethernet
            eth.setNextPDU(arp);

            //To make things more interesting let's add a Vlan Tag to Ethernet frame
            //Just for Fun :)-
            eth.addVlanTag((short)2,(byte)100,true);

            //Start your capture before Here!
            cap.sendFrame(eth);

            //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 (IllegalPduExecption e) {
            System.err.println("Ops... Corrupted Pdu");
            e.printStackTrace();
        } catch (NotSupportedDatalinkS4JException e) {

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

This example shows how to create an Arp packet and inject it to the network.
You have to be aware that you have to create the whole Pdu chain in order to this injected packet, be a valid packet.

First of all, in an Ethernet network, the first Pdu is always an EthernetPdu (obviously).
So we create a EthernetPdu with the fake mac address (destination 0:1:2:3:4:5 Source 0:1:2:3:4:6:5)

EthernetPdu eth = new EthernetPdu(destinationMac,sourceMac, EtherTypeProtocol.ARP);

Them we create the ArpPdu

ArpPdu arp = new ArpPdu(destinationMac,destinationMac,destinationMac,
                    destinationMac,EtherTypeProtocol.IPX,ArpProtocol.ARP_OP_REQ_CODE);

This is a syntactically bogus Arp Pdu, but at the same time is completely well formed in its structure. We said that this Arp Pdu have the protocol address the same as hardware address and the application that this packet is intended for is Ipx (?!) nonsense I know, but at the same time, if you sniff this packet in a Wireshark while it is injected to the network if will say that it is a valid ArpPdu (at least in form and structure).
My intentions with Sniffer4J at this point is not to teach you about network protocol (You should already know something by this point), but let you test the limits of you network and net devices.

We create the Pdu chain by attaching the ArpPdu as the nextPDU of EthernetPdu

eth.setNextPDU(arp);

The chain is now

eth -> arp -> null

Finally we just send the packet

cap.sendFrame(eth);

Remember, it is user responsibility to populate ALL the Pdu fields with proper values, this means that fields like payloadlength, and next protocol value should be set by the user with appropriate value regarding the Pdu chain created.

In this example we needed to explicitly set the EtherType field of Ethernet Pdu with the value for the Arp protocol.
If you are dealing with protocols with length field (like Ip or Udp) you need to explicit set those values according to the length of the chain. In [Testing Sniffer4J] you can see more about how to do it properly. I'm also working in chain Builder to help adjust the chain once it is created. I hope you see those functionalities in next versions of Sniffer4J and later tutorial.


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.