Change packet ip using Pcap.Net without know in advance if the packet is TCP, UDP

1.6k Views Asked by At

In my application I am using Pcap.net DLLs and change packet ip in this way:

private Packet ChangePacketIp(Packet packet, string oldIpAddress, string newIpAddress)
{
    try
    {
        EthernetLayer ethernet = (EthernetLayer)packet.Ethernet.ExtractLayer();
        IpV4Layer ipV4Layer = (IpV4Layer)packet.Ethernet.IpV4.ExtractLayer();
        DateTime packetTimestamp = packet.Timestamp;

        if (packet.Ethernet.IpV4.Source.ToString() == oldIpAddress)
        {
            ipV4Layer.Source = new IpV4Address(newIpAddress);
            ipV4Layer.HeaderChecksum = null;
        }
        else if (packet.Ethernet.IpV4.Destination.ToString() == oldIpAddress)
        {
            ipV4Layer.CurrentDestination = new IpV4Address(newIpAddress);
            ipV4Layer.HeaderChecksum = null;
        }

        if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Tcp)
        {
            TcpLayer tcpLayer = (TcpLayer)packet.Ethernet.IpV4.Tcp.ExtractLayer();
            tcpLayer.Checksum = null;
            ILayer payload = packet.Ethernet.IpV4.Tcp.Payload.ExtractLayer();
            return PacketBuilder.Build(packetTimestamp, ethernet, ipV4Layer, tcpLayer, payload);
        }
        else if (packet.Ethernet.IpV4.Protocol == IpV4Protocol.Udp)
        {
            UdpLayer udpLayer = (UdpLayer)packet.Ethernet.IpV4.Udp.ExtractLayer();
            udpLayer.Checksum = null;
            ILayer payload = packet.Ethernet.IpV4.Udp.Payload.ExtractLayer();
            return PacketBuilder.Build(packetTimestamp, ethernet, ipV4Layer, udpLayer, payload);
        }
        else
        {
            return null;
        }
    }
    catch (Exception)
    {
        return null;
    }
}

In case I have VLAN packet packet.Ethernet.IpV4.Protocol is different than TCP although the packet is TCP and in this case I return null, any way how to achieve my purpose without knowing in advance what my packet protocol?

2

There are 2 best solutions below

3
On

PCap.NET lib was rewritten from C lib and as far as I checked, it was not very well OO, so you have to verify packets using conditional operators.

Here is the source code: http://pcapdotnet.codeplex.com/SourceControl/latest#PcapDotNet/src/

Tip: Avoid compare IP as string. Prefer integer (IPv4), are safer and faster.

// Example: IPv4 convertion

int intAddress = BitConverter.ToInt32(IPAddress.Parse(address).GetAddressBytes(), 0);
string ipAddress = new IPAddress(BitConverter.GetBytes(intAddress)).ToString();

You could create an interface to abstract packet information, to enable classes speak with each other (Adaptor Design Patterns), but soon or later you have to detect each type of packet. Otherwise, you could modify PCapLib to enable it. For example:

  1. Create an abstract method that return all packet info you need and each class must implement it (TCP, UDP, ICMP classes), adding some methods (e.g. to receive source/destination IP, source/destination port, etc). The main idea is to use polimorphism.

  2. Modify PacketBuilder.Build to accept those parameters.

0
On

You can check whether the EthernetDatagram contains a VLAN datagram by checking the EthernetDatagram.EtherType field.

If it does, you should get to your IPv4 layer by doing

packet.Ethernet.VLanTaggedFrame.IpV4