Menu

Tutorial 4 Example 2

Bernardo Bulgarelli Labronici

Example 2

Sending the following packets

  • Ethernet II
  • Ethernet I (Llc and Llc + Snap)
  • Ethernet I Raw with Ipx
  • Arp
  • Ipx
  • IpV4 and Tcp (With some Ip Options)
  • IpV6 and Tcp (With some Ip Options)

It is possible to easilly see this packets been sent to network with Wireshark https://www.wireshark.org/
just use the follow filter

eth.dst == 00:01:02:03:04:05

This filter will only allow packets with the above mac address.

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!!

Make sure there is no Mac address 00:01:02:03:05:06, or Ip address 1.2.3.4 or 2.3.4.5, if so change it accordingly

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

            //Several Packets to send
            EthernetPdu eth = new EthernetPdu(destinationMac,sourceMac, EtherTypeProtocol.ARP);

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

            Address sourceIp = Address.getIpAddress(
                    InetAddress.getByName("1.2.3.4").getAddress());
            Address destIp = Address.getIpAddress(
                    InetAddress.getByName("2.3.4.5").getAddress());

            IpV4Pdu ipV4 = new IpV4Pdu(sourceIp, destIp, IpProtocol.TCP);
            ipV4.setTimeToLive((byte)10);


            TcpPdu tcp = new TcpPdu((short)100,(short)200);
            tcp.setWindowSize((short)100);

            UdpPdu udp = new UdpPdu((short)110,(short)220);

            LlcPdu llc = new LlcPdu(LlcProtocol.SNAP,LlcProtocol.SNAP);

            //###########
            //Create a Stream Option
            List<IpV4Option> optionsList = new ArrayList<IpV4Option>();
            IpV4StreamOptionValue strOption = new IpV4StreamOptionValue((short)10);
            IpV4Option ipOption = new IpV4Option(
                    IpV4OptionsProtocol.STREAM_IDENTIFIER, strOption);


            //##############
            //Create a Record Route Option
            Address[] addr = new Address[2];
            addr[0] = sourceIp;
            addr[1] = destIp;
            //Pointer have to point to Address inside this option
            IpV4SourceRecordOptionValue recOption = new 
                    IpV4SourceRecordOptionValue(
                            (byte)(
                                    eth.getLength() + 
                                    ipV4.getIhl() * 4 + 
                                    strOption.getLength()), addr);          
            IpV4Option ipOption2 = new IpV4Option(
                    IpV4OptionsProtocol.RECORD_ROUTE, recOption);

            //##############
            //Create a timestamp option
            int[] timestamps = new int[]{127,1000};
            IpV4TimestampOptionValue timeOption = new
                    IpV4TimestampOptionValue(timestamps, addr);
            IpV4Option ipOption3 = new IpV4Option(
                    IpV4OptionsProtocol.INTERNET_TIMESTAMP, timeOption);

            //Add options to list
            optionsList.add(ipOption);
            optionsList.add(ipOption2);
            optionsList.add(ipOption3);

            byte[] oui = new byte[3];
            SnapPdu snap = new SnapPdu(oui,EtherTypeProtocol.IPV4);

            IpxPdu ipx = new IpxPdu(sourceIp, destIp, 
                    sourceMac, destinationMac, 
                    IpxProtocol.PEP);

            IpxSapPdu sap = new IpxSapPdu(
                    IpxSapServiceProtocol.PRINTQUEUE,
                    IpxSapPacketTypeProtocol.RESPONSE_GENERAL,
                    sourceIp,
                    destinationMac);

            sap.setServerName(
                    "Can convert Java UTF-8 direct to ASCII as long as there is no special characters".getBytes());

            //SAP port
            ipx.setDestSocketCode((short)0x0452);
            ipx.setNextPDU(sap);
            ipx.setIpxLength((short)(ipx.getLength() + sap.getLength()));;

            Address sourceIpV6 = Address.getIpAddress(
                    InetAddress.getByName("FFFF::1234:1232").getAddress()
                    );
            Address destinationIpV6 = Address.getIpAddress(
                    InetAddress.getByName("FFFF:FFFF::4433:4433").getAddress()
                    );
            IpV6Pdu ipV6 = new IpV6Pdu(sourceIpV6, destinationIpV6, IpProtocol.TCP);



            //# SENDING ################################
            //Send Ethernet II + Arp
            eth.setNextPDU(arp);                    
            cap.sendFrame(eth);

            //# SENDING ################################
            //EthernetII + Ipv4( with Options) + Tcp
            eth.setEtherType(EtherTypeProtocol.IPV4);
            ipV4.setNextPDU(tcp);
            ipV4.setOptions(optionsList);
            ipV4.setTotalLength((short)(ipV4.getLength() + tcp.getLength()));
            eth.setNextPDU(ipV4);                   
            cap.sendFrame(eth);

            //# SENDING ################################
            //EthernetI + LLC +SNAP + Ipv4 + Tcp
            ipV4.setOptions(null);
            ipV4.setTotalLength((short)(ipV4.getLength() + tcp.getLength()));
            short ethLength = (short)(llc.getLength() + snap.getLength() + ipV4.getTotalLength());
            eth.setEtherTypeCode(ethLength);
            eth.setNextPDU(llc);
            llc.setNextPDU(snap);
            snap.setNextPDU(ipV4);
            cap.sendFrame(eth);

            //# SENDING ################################
            //EthernetII + Ipv4 + Udp
            eth.setEtherType(EtherTypeProtocol.IPV4);
            ipV4.setNextPDU(udp);
            ipV4.setProtocol(IpProtocol.UDP);
            ipV4.setTotalLength((short)(ipV4.getLength() + udp.getLength()));
            udp.setLengthPdu((short)udp.getLength());
            eth.setNextPDU(ipV4);                   
            cap.sendFrame(eth);

            //# SENDING ################################
            //EthernetI + Ipx (Raw Ipx)+SAP
            eth.setEtherTypeCode((short)ipx.getIpxLength());
            eth.setNextPDU(ipx);
            cap.sendFrame(eth);

            //# SENDING ################################
            //EthernetI + LLC + Ipx +SAP
            eth.setEtherTypeCode((short)(ipx.getIpxLength() + llc.getLength()));
            eth.setNextPDU(llc);
            llc.setDsap(LlcProtocol.NETWARE);
            llc.setNextPDU(ipx);
            cap.sendFrame(eth);

            //# SENDING ################################
            //EthernetII + Ipx +SAP
            eth.setEtherType(EtherTypeProtocol.IPX);
            eth.setNextPDU(ipx);
            cap.sendFrame(eth);

            //# SENDING ################################
            //EthernetII + IpV6 + Tcp
            eth.setEtherType(EtherTypeProtocol.IPV6);
            eth.setNextPDU(ipV6);
            ipV6.setNextPDU(tcp);
            ipV6.setPayLoadLength((short)tcp.getLength());
            cap.sendFrame(eth);

            //Tunnel option
            IpV6TunnelEncapsulatonLimitOptionValue tunnel = new 
                    IpV6TunnelEncapsulatonLimitOptionValue((byte)13);
            IpV6Option opt1 = new IpV6Option(IpV6OptionsProtocol.TUNNELENCLIMIT, tunnel);

            //Set a Jumbosize Option for Ipv6 
            IpV6JumbogramsOptionValue jumbo = new IpV6JumbogramsOptionValue(65536);
            IpV6Option opt2 = new IpV6Option(IpV6OptionsProtocol.JUMBOGRAMS,jumbo);

            //Set  Route Alert Option
            IpV6RouterAlertOptionValue alert = new IpV6RouterAlertOptionValue((short) 2);
            IpV6Option opt3 = new IpV6Option(IpV6OptionsProtocol.ROUTERALERT,alert);

            //Set a Route Alert Option
            IpV6RPLOptionValue rpl = new IpV6RPLOptionValue(null);
            IpV6Option opt4 = new IpV6Option(IpV6OptionsProtocol.RPL, rpl);



            List<IpV6Option> options = new ArrayList<IpV6Option>();
            options.add(opt1);
            options.add(opt2);
            options.add(opt3);
            options.add(opt4);

            IpV6OptionHeaderPdu header = 
                    new IpV6OptionHeaderPdu(IpProtocol.TCP, options);
            header.setNextPDU(tcp);

            //# SENDING ################################
            //EthernetII + IpV6 (Options) + Tcp
            eth.setEtherType(EtherTypeProtocol.IPV6);
            eth.setNextPDU(ipV6);
            ipV6.setNextHeader(IpProtocol.IPV6_HOPBYHOP);
            ipV6.setNextPDU(header);
            //For jumbo Frames the payload should be Zero (see opt 2 added to this Pdu)
            //There will be an alert for thi Pdu, since it's size should be 65536
            //Most NIC will not allow frames greater than 1514 bytes.
            //you should try sending jumbo frames, but be advise, that if
            //if fails it not an Sniffer4J problem.
            ipV6.setPayLoadLength((short)0);
            cap.sendFrame(eth);

            LldpPdu lldp = new LldpPdu(destinationMac,(short)123);

            //# SENDING ################################
            //EthernetII + LLDP  (MAC address of Ethernet packet should be set to
            //mac multicast address according to IEEE 802.ab standards; but you
            // can get an idea from this example)
            eth.setEtherType(EtherTypeProtocol.LLDP);
            eth.setNextPDU(lldp);
            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 (UnknownHostException e) {

            System.err.println("Ops... This is Not an IP address");
            e.printStackTrace();
        } catch (NotSupportedDatalinkS4JException e) {

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

Things worth to mentions…

Some types of Pdu have a great variation in terms of data. The Ip option field is one of those cases. Each option is a TLV (type length value) field. Once more, the value field can have a wild variation, almost one per type.
In such way TcpOption, IpV4Option, IpV6Option, LldpTLV and all Icmp messages follow this pattern:

  • There is an abstract class to represent the value field called Value Class
  • There is a base Class (Base) with a data field to the Value Class
  • Each type have a proper concrete Class of Value
  • The follow diagram class give an brief idea of the concept.

BaseClass


Related

Wiki: Tutorial 4 Example 3
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.