Packet manipulation ?

Mar 25, 2012 at 7:23 PM

hi,

 

i am using pcapdotnet to send packets using send buffer with Wireshark ile (pcap extension) and my question is there is any way to change the packets IP during or before play ?

Coordinator
Mar 25, 2012 at 7:26 PM

Yes,

 

You can read each packet, extract the relevant layers from the packet (Ethernet, IPv4 and the IPv4 payload), change the IPv4 layer and build a new packet.

 

I hope this helps,

 

Boaz.

Mar 25, 2012 at 8:10 PM

thanks for your help !

 

can i have example how to do it ?

Coordinator
Mar 28, 2012 at 12:11 PM

Of the top of my head (probably doesn't compile):

 

IpV4Layer newIpV4Layer = packet.Ethernet.IpV4.ExtractLayer();

newIpV4Layer.Destination = new IpV4Address("1.2.3.4");

Packet newPacket = PacketBuilder.Build(DateTime.Now, packet.Ethernet.ExtractLayer(), newIpV4Layer, packet.Etherent.IpV4.Payload.ExtractLayer());

 

I hope this helps,

 

Boaz.

Mar 28, 2012 at 7:02 PM
Edited Mar 30, 2012 at 2:56 PM

this is what i try till now:

IpV4Layer ipLayer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
ipLayer.Destination = new IpV4Address("11.12.13.14");
EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
PayloadLayer payload = (PayloadLayer)packet.Ethernet.Payload.ExtractLayer();
Packet newPacket = PacketBuilder.Build(DateTime.Now, ethernet, ipLayer, ipLayer, payload);
sendBuffer.Enqueue(newPacket);

in the last line error received:  Failed enqueueing to SendQueue
Coordinator
Mar 30, 2012 at 5:10 PM

Hi,

 

You probably need to allocate a big enough send buffer.

I suggest not jumping into send buffer before you manage to make everything working.

Just send each packet separately using communicator.SendPacket().

 

If you have want to make sure the checksum is correct, you will need to reset it to null:

ipLayer.HeaderChecksum = null;

This will make make the PacketBuilder recalculate the header checksum to make it correct.

 

If you have UDP and TCP layers and you want to keep their checksum correct as well, you will have to extract the transport layer like you extracted the IPv4 layer and reset its checksum as well.

TransportLayer transportLayer = (TransportLayer)packet.Ethernet.IpV4.Transport.ExtractLayer();

transportLayer.Checksum = null;

Don't forget to extract the payload of the TCP or UDP datagram and extract a layer from that as well in order to make sure you don't lose it.

 

I hope this helps,

 

Boaz.

Mar 30, 2012 at 5:36 PM

u suggest to do nothing inside while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok) and after the while try to send 1 packet ?

Coordinator
Mar 30, 2012 at 5:59 PM

Please post the relevant code here.

 

You can just use PacketCommunicator.SendPacket() instead of en-queuing it in the SendBuffer (inside the loop).

Mar 30, 2012 at 7:36 PM
Edited Mar 30, 2012 at 7:39 PM

i build application who take Wireshark file and send all the packets with send buffer (the example who come with the DLLs package) and i want the option to change the file IP and send the buffer with different Ip, that is why i want to use send buffer option:

                        // Fill the buffer with the packets from the file

                        int numPackets = 0;

                        Packet packet;


                        while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)                        {
                            sendBuffer.Enqueue(packet);

                            ++numPackets;

                       }

 

i want to do it ongoing, just to change all the packets Ip inside the buffer and than send it, is it possible ?

Coordinator
Mar 30, 2012 at 8:15 PM

Yes.

 

You'll just have to recreate new send buffers and decide when to transmit the packets.

The point of the send buffers is to efficiently send a group of packets, if you want to manipulate each packet and send it separately, use the SendPacket() function which also has an example in the dll package.

Mar 30, 2012 at 9:40 PM
Edited Mar 30, 2012 at 9:42 PM

Thank you for your help !

i prefer to use send buffer because i am working with Wireshark files who contain many packets.

so i need to work on each packet from my buffer (and change whatever i want) and fill the buffer with the new packets and send ?

can you please show me how to change the packet ? 

Coordinator
Mar 31, 2012 at 7:36 AM

It seems that you've already done it.

You just need to extract the layers you want to build the packet form.

Change them (Change IPv4 layer's Source or Destination, set HeaderChecksum to null in IPv4 and Checksum to null in UDP layer or TCP layer).

Build a new packet from the modified layers.

 

I suggest debugging this by using Wireshark and sniff the packets you send or by sending the packets to a pcap file directly and then looking at them.

 

I hope this helps,

 

Boaz.

Mar 31, 2012 at 7:45 AM
Edited Mar 31, 2012 at 7:47 AM

i am using Wireshark in order to see how my new packet looks like after sending it.

so you telling me that my code and the new packet build looks correct ? so why i am cannot send the buffer ? (

Failed enqueueing to SendQueue error - see my Fri at 10:36 PM post)

can show me shoe to how set HeaderChecksum to null in IPv4 and Checksum to null in UDP layer or TCP layer ?
this is my code:

                        int numPackets = 0;
                        Packet packet;
                        while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
                        {
                            IpV4Layer ipLayer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
                            ipLayer.Destination = new IpV4Address("11.12.13.14");
                            EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
                            PayloadLayer payload = (PayloadLayer)packet.Ethernet.Payload.ExtractLayer();
                            Packet newPacket = PacketBuilder.Build(DateTime.Now, ethernet, ipLayer, ipLayer, payload);
                            sendBuffer.Enqueue(newPacket);
                            ++numPackets;
                        }

Coordinator
Mar 31, 2012 at 7:50 AM

You might not have allocated enough space in the buffer.

As I mentioned, please try and use SendPacket() and only after you make it working try to move to send buffer if it's really necessary.

Mar 31, 2012 at 7:56 AM
Edited Mar 31, 2012 at 7:58 AM

do you mean inputCommunicator.SendPacket(newPacket) instead of sendBuffer.Enqueue(newPacket) ?

cause error Failed writing to device. WinPcap Error: Sending packets isn't supported on save files received

 

can you help me and show me quick example on my code how to do it ? 

Coordinator
Mar 31, 2012 at 8:08 AM

ok, you're trying to send packets to the pcap file you're reading from and of course this won't work.

You need to use a network device and open a communicator on it in order to send packets on the network.

SendPacket() and Transmit() are for sending packets to the network, not for writing packets to a pcap file.

Mar 31, 2012 at 8:14 AM

i need to change the packet before i am fill the buffer with the packets from the file ?

                    // Allocate a send buffer
                    using (PacketSendBuffer sendBuffer = new PacketSendBuffer((uint)capLength))
                    {
			******* here i need to change the packet ??? *******
                        // Fill the buffer with the packets from the file
                        int numPackets = 0;
                        Packet packet;
                        while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
                        {
                            IpV4Layer ipLayer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
                            ipLayer.Destination = new IpV4Address("11.12.13.14");
                            EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
                            PayloadLayer payload = (PayloadLayer)packet.Ethernet.Payload.ExtractLayer();
                            Packet newPacket = PacketBuilder.Build(DateTime.Now, ethernet, ipLayer, ipLayer, payload);
                            inputCommunicator.SendPacket(newPacket);
                            //sendBuffer.Enqueue(newPacket);
                            ++numPackets;
                        }

                        outputCommunicator.Transmit(sendBuffer, isSync); //Transmit the queue
                    }
Coordinator
Mar 31, 2012 at 8:18 AM

No, where you cahnge the packet seems fine.

I'm not sure why you build a new packet with two ip layers. Are you trying to create an IP over IP packet?

You can add 

ipLayer.HeaderChecksum = null;

If you want to recalculate the checksum so it would be valid.

UDP or TCP checksums still won't be valid.

 

If you use SendPacket you can remove (or comment out) all traces of the send buffer.

 

What doesn't work now?

Mar 31, 2012 at 8:23 AM
Edited Mar 31, 2012 at 8:33 AM

why i am build a new packet with two ip layers ? i only change the IP once (to 11.12.13.14)

as i told you before Failed writing to device. WinPcap Error: Sending packets isn't supported on savefiles under 

 

inputCommunicator.SendPacket(newPacket)

 

BTW how to recalculate UDP or TCP checksums ?

 

update: the 2 ip layer was mistake and new i can send the packet with send buffer, the only issue now is:

http://42.imagebam.com/download/TitKkmshZvHHuXtsmwj--A/18246/182459053/Untitled.jpg

Mar 31, 2012 at 12:15 PM
Edited Mar 31, 2012 at 12:15 PM

OK 2 new issues:

i try to allocate bigger buffer by multiple the actual size in 2:

 

                    // Allocate a send buffer
                    using (PacketSendBuffer sendBuffer = new PacketSendBuffer((uint)capLength * 2))

 

1. now i can send more than 1 packet but after few packets (30-40) i have crash with error Failed transmiting packets from queue. WinPcap Error: Error opening adapter: Error opening adapter: Error opening adapter: Error under Transmit command

2. http://42.imagebam.com/download/TitKkmshZvHHuXtsmwj--A/18246/182459053/Untitled.jpg

i still see that the packet is corrupt, you wrote UDP or TCP checksums still won't be valid - how to fix it ?

Thanks and Hag Samech.

Coordinator
Mar 31, 2012 at 1:42 PM

1. As I said, please try to resolve all other issues before trying to use send buffers. You need to allocate enough space there for all packets you transmit, and not just 2.

2. Assuming the problem is indeed due to TCP checksum (which makes a lot of sense), you need to also extract the TCP layer from the TCP datagram and set the checksum to null.

TcpLayer tcpLayer = (TcpLayer)packet.Etherent.IpV4.Tcp.ExtractLayer();

tcpLayer.Checksum = null;

PayloadLayer = (PayloadLayer)packet.Etherent.IpV4.Tcp.Payload.ExtractLayer();

...BuildPacket(..., tcpLayer, payloadLayer);

 

I hope this helps,

 

Boaz.

Mar 31, 2012 at 3:09 PM
Edited Mar 31, 2012 at 3:50 PM

how to allocate enough space ?


Coordinator
Mar 31, 2012 at 3:26 PM
psptst1 wrote:

who to allocate enough space ?


When creating the PacketSendBuffer you need to give it a big enough length as the constructor parameter so it would be able to hold all the packets you want to transmit.

Mar 31, 2012 at 3:41 PM
Edited Mar 31, 2012 at 3:54 PM

i don't think this is the problem, i define PacketSendBuffer size to uint.MaxValue (capLenth = uint.MaxValue) and try to play file with 6300 packets (small file) and now when build the packet Index was outside the bounds of the array error and also i can see when compare packct to the newPacket that the data in the newPacket increase more 10 times, whats the reason ?

 

                    // Allocate a send buffer
                    using (PacketSendBuffer sendBuffer = new PacketSendBuffer((uint)capLength))
                    {
                        // Fill the buffer with the packets from the file
                        int numPackets = 0;
                        Packet packet;
                        while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
                        {
                            EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
                            PayloadLayer payload = (PayloadLayer)packet.Ethernet.Payload.ExtractLayer();
                            TcpLayer tcpLayer = (TcpLayer)packet.Ethernet.IpV4.Tcp.ExtractLayer();
                            tcpLayer.Checksum = null;
                            UdpLayer udpLayer = (UdpLayer)packet.Ethernet.IpV4.Udp.ExtractLayer();
                            udpLayer.Checksum = null;
                            IpV4Layer ipLayer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
                            ipLayer.Destination = new IpV4Address("11.12.13.14");
                            ipLayer.HeaderChecksum = null;
                            Packet newPacket = PacketBuilder.Build(DateTime.Now, ethernet, ipLayer, payload, tcpLayer);
                            sendBuffer.Enqueue(newPacket);
                            ++numPackets;
                        }

                        outputCommunicator.Transmit(sendBuffer, isSync); //Transmit the queue
                    }

 

Coordinator
Mar 31, 2012 at 4:38 PM

First, try to allocate uint.MaxValue bytes would probably won't work because in most computers you won't be able to allocation consecutive 4GB of RAM.

Second, the payload layer should be after the TCP layer.

Third, you don't use the UDP layer so it has no affect.

Fourth, please post the entire exception details including the call stack so I can try and help you.

Mar 31, 2012 at 4:46 PM
Edited Mar 31, 2012 at 5:12 PM

i have change the buffer size to my file size (capLenth):

 

            // Retrieve the length of the capture file
            long capLength = new FileInfo("C:\\smtp.pcap").Length;

 

my code:

 

                    // Allocate a send buffer
                    using (PacketSendBuffer sendBuffer = new PacketSendBuffer((uint)capLength))
                    {
                        // Fill the buffer with the packets from the file
                        int numPackets = 0;
                        Packet packet;
                        while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
                        {
                            EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
                            PayloadLayer payload = (PayloadLayer)packet.Ethernet.Payload.ExtractLayer();
                            TcpLayer tcpLayer = (TcpLayer)packet.Ethernet.IpV4.Tcp.ExtractLayer();
                            tcpLayer.Checksum = null;
                            UdpLayer udpLayer = (UdpLayer)packet.Ethernet.IpV4.Udp.ExtractLayer();
                            udpLayer.Checksum = null;
                            IpV4Layer ipLayer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
                            ipLayer.Destination = new IpV4Address("11.12.13.14");
                            ipLayer.HeaderChecksum = null;
                            Packet newPacket = PacketBuilder.Build(DateTime.Now, ethernet, ipLayer, tcpLayer, udpLayer, payload);
                            sendBuffer.Enqueue(newPacket);
                            ++numPackets;
                        }

                        outputCommunicator.Transmit(sendBuffer, isSync); //Transmit the queue
                    }

 

when the buffer size is as my file:

http://17.imagebam.com/download/zlpNeLzo7hqm4BNH92q_Lw/18253/182527617/error.jpg - Failed enqueueing to SendQueue

when the buffer size is as (my file) x 2:

http://65.imagebam.com/download/Ihi5s_dIrnuhdaNrL-fMnw/18253/182528952/2.jpg - Failed transmiting packets from queue. WinPcap Error: Error opening adapter: Error opening adapter: Error opening adapter: Error

Thanks for your help !

Coordinator
Mar 31, 2012 at 6:30 PM

You put both TCP layer and UDP layer in the packet, which makes no sense.

If the packet is TCP you need to put TCP, if the packet is UDP, you need to put UDP.

 

As I said, first try and use SendPacket() and only after everything works for you consider using PacketSendBuffer as it adds complications that you shouldn't bother with at first try.

Mar 31, 2012 at 7:57 PM
Edited Mar 31, 2012 at 8:09 PM

i have send 2 packets using  SendPacket() but it's seems that they corrupt:

http://70.imagebam.com/download/uN6pIbq2oymdO8yHJ-msYw/18256/182553771/5.jpg

Coordinator
Mar 31, 2012 at 8:04 PM

I have no idea, if you still use both TCP layer and UDP layer it won't work.

I need to see the pcap file you create and the code you use.

Mar 31, 2012 at 8:32 PM
Edited Mar 31, 2012 at 8:33 PM

the code:

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using PcapDotNet.Core;
using PcapDotNet.Packets;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Ethernet;
using PcapDotNet.Packets.Transport;

namespace SendingPacketsUsingSendBuffer
{
    class Program
    {
        static void Main(string[] args)
        {
            // Check the validity of the command line
            if (args.Length == 0 || args.Length > 2)
            {
                //return;
            }

            // Retrieve the device list from the local machine
            IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine;

            if (allDevices.Count == 0)
            {
                Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
                return;
            }

            // Print the list
            for (int i = 0; i != allDevices.Count; ++i)
            {
                LivePacketDevice device = allDevices[i];
                Console.Write((i + 1) + ". " + device.Name);
                if (device.Description != null)
                    Console.WriteLine(" (" + device.Description + ")");
                else
                    Console.WriteLine(" (No description available)");
            }

            int deviceIndex = 0;
            do
            {
                Console.WriteLine("Enter the interface number (1-" + allDevices.Count + "):");
                string deviceIndexString = Console.ReadLine();
                if (!int.TryParse(deviceIndexString, out deviceIndex) ||
                    deviceIndex < 1 || deviceIndex > allDevices.Count)
                {
                    deviceIndex = 0;
                }
            } while (deviceIndex == 0);

            // Take the selected adapter
            PacketDevice selectedOutputDevice = allDevices[deviceIndex - 1];

            uint bufferSize = uint.MaxValue;

            // Retrieve the length of the capture file
            long capLength = new FileInfo("C:\\28.pcap").Length;

            // Chek if the timestamps must be respected
            bool isSync = (args.Length == 2 && args[1][0] == 's');

            // Open the capture file
            OfflinePacketDevice selectedInputDevice = new OfflinePacketDevice("C:\\28.pcap");

              // 65536 guarantees that the whole packet will be captured on all the link layers
             // promiscuous mode
            // read timeout
            using (PacketCommunicator inputCommunicator = selectedInputDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000))// portion of the packet to capture
            {
                using (PacketCommunicator outputCommunicator =  selectedOutputDevice.Open(100, PacketDeviceOpenAttributes.Promiscuous, 1000))
                {
                    // Allocate a send buffer
                    using (PacketSendBuffer sendBuffer = new PacketSendBuffer((uint)capLength))
                    {
                        // Fill the buffer with the packets from the file
                        int numPackets = 0;
                        Packet packet;
                        while (inputCommunicator.ReceivePacket(out packet) == PacketCommunicatorReceiveResult.Ok)
                        {
                            EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
                            PayloadLayer payload = (PayloadLayer)packet.Ethernet.Payload.ExtractLayer();
                            TcpLayer tcpLayer = (TcpLayer)packet.Ethernet.IpV4.Tcp.ExtractLayer();
                            tcpLayer.Checksum = null;
                            //UdpLayer udpLayer = (UdpLayer)packet.Ethernet.IpV4.Udp.ExtractLayer();
                            //udpLayer.Checksum = null;
                            IpV4Layer ipLayer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
                            ipLayer.Destination = new IpV4Address("11.12.13.14");
                            ipLayer.HeaderChecksum = null;
                            Packet newPacket = PacketBuilder.Build(DateTime.Now, ethernet, ipLayer, tcpLayer, payload);
                            //sendBuffer.Enqueue(newPacket);
                            outputCommunicator.SendPacket(newPacket);
                            ++numPackets;
                        }

                        //outputCommunicator.Transmit(sendBuffer, isSync); //Transmit the queue
                    }
                }
            }
        }
    }
}

 

the 2 files (pcap files, before and after):

http://www.2shared.com/file/yUY6NYKP/Desktop.html

Apr 2, 2012 at 7:01 PM

any ideas ?

Coordinator
Apr 6, 2012 at 6:53 AM
psptst1 wrote:

i have send 2 packets using  SendPacket() but it's seems that they corrupt:

http://70.imagebam.com/download/uN6pIbq2oymdO8yHJ-msYw/18256/182553771/5.jpg

Actually, looking at that picture, I don't see what is corrupted.

What do you think this packet is corrupted?

Apr 6, 2012 at 9:34 PM
Edited Apr 6, 2012 at 9:49 PM

the original packet has different color and this packet all in black, in addition on each packet i see the message TCP out-of-order segment (Wireshark main screen)

and another question:

when i am try to play bigger file and allocate bigger buffer i am still cannot play all the file and crash with Failed writing to device. WinPcap Error: send error: PacketSendPacket failed error

i am allocate buffer size like my file and even bigger up to 10 times

Coordinator
Apr 7, 2012 at 8:44 AM

Anyways, the packet you have in the picture looks ok.

The TCP out-of-order only talks about how this packet is relative to other packets in the TCP session. It doesn't mean it's a bad packet.

I suggest reading a bit on TCP, which would make these things more clear.

 

As I said before, try to have everything working without the send buffer and only after that you can try and integrate it.

Apr 7, 2012 at 10:20 AM

i am using send packet and not send buffer

Coordinator
Apr 7, 2012 at 1:31 PM
psptst1 wrote:

the original packet has different color and this packet all in black, in addition on each packet i see the message TCP out-of-order segment (Wireshark main screen)

and another question:

when i am try to play bigger file and allocate bigger buffer i am still cannot play all the file and crash with Failed writing to device. WinPcap Error: send error: PacketSendPacket failed error

i am allocate buffer size like my file and even bigger up to 10 times

What do you mean "i am allocate buffer size"?

What buffer are you allocating if you don't use the send buffer?

Apr 7, 2012 at 3:49 PM

my mistake, my last code is what i am use now so i guess allocate buffer is useless (and harmless) but still why i cannot send all the packets ?

Coordinator
Apr 7, 2012 at 4:59 PM

I don't understand.

What do you mean by "why i cannot send all the packets ?"?

What error do you get?

Can you give the entire exception details and call stack?

Why do you open the output communicator using 100 as the snapshot length?

Why do you use two communicators?

Apr 7, 2012 at 5:20 PM

honesty, until now i only use send buffer (that's why i use the example from send buffer) so i will be glad if you can show me how to use send packet or explain me how to do it

Coordinator
Apr 7, 2012 at 5:26 PM

In the last piece of code you've written above you seem to use the SendPacket().

There are also examples to use the SendPacket() in the tutorial.

Apr 8, 2012 at 8:30 AM

i will check this example.

what is the different between send buffer and send packet ? (in case i want to send all the packets from my file using send packet)

Coordinator
Apr 8, 2012 at 12:18 PM

A quote from the user guide:

"

While SendPacket() offers a simple and immediate way to send a single packet, send buffers provides an advanced, powerful and optimized mechanism to send a collection of packets. A send buffer is a container for a variable number of packets that will be sent to the network. It has a size, that represents the maximum amount of bytes it can store.

"

Dec 23, 2015 at 2:19 AM
hello every body, i want to capture dns, ssl/tls packets with pcap.net. is it possible to do it? if yes then please let me know some examples if you have.
thanks
Coordinator
Feb 5, 2016 at 10:08 AM
Hi MuhammadAzeem,

This seems unrelated to the topic.
Please use Pcap.Net Q&A group to post new questions.
A .pcap file as an example for what you want to capture would be helpful.

Boaz.