0

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?

Xm7X
  • 861
  • 1
  • 11
  • 23
Mike Maggy
  • 93
  • 2
  • 14

2 Answers2

0

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.

Icaro Camelo
  • 382
  • 1
  • 10
  • What do u mean Prefer integer ? – Mike Maggy Nov 19 '14 at 21:20
  • @MikeMaggy I meant: handle IP with integer is safer and faster way. IP Addressing has 32 bits of information, so you could express IP addresses as integer. Strings are too flexible, per exemple: " 127.0.0.1" is different of "127.0.0.1". Even white spaces might lead to errors. In low level, comparing integers are faster than comparing strings. – Icaro Camelo Nov 20 '14 at 02:38
  • Ok that fine but what about my question about change the packet ip without know in advance if the packet is TCP, UDP etc. ? – Mike Maggy Nov 20 '14 at 10:34
0

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
brickner
  • 6,595
  • 3
  • 41
  • 54