【问题标题】:Change packet ip using Pcap.Net without know in advance if the packet is TCP, UDP使用 Pcap.Net 更改数据包 ip 无需事先知道数据包是 TCP、UDP
【发布时间】:2015-01-17 10:48:29
【问题描述】:

在我的应用程序中,我使用Pcap.net DLL 并以这种方式更改数据包 IP:

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;
    }
}

如果我有 VLAN packet packet.Ethernet.IpV4.ProtocolTCP 不同,尽管数据包是 TCP 并且在这种情况下我返回 null,在不事先知道我的数据包协议的情况下如何实现我的目的?

【问题讨论】:

    标签: c# .net networking pcap pcap.net


    【解决方案1】:

    PCap.NET lib 是从 C lib 重写的,据我检查,它不是很好的 OO,因此您必须使用条件运算符来验证数据包。

    这里是源代码:http://pcapdotnet.codeplex.com/SourceControl/latest#PcapDotNet/src/

    提示:避免将 IP 作为字符串进行比较。首选整数 (IPv4),更安全、更快捷。

    // 示例:IPv4 转换

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

    您可以创建一个接口来抽象数据包信息,以使类能够相互交流(适配器设计模式),但迟早您必须检测每种类型的数据包。否则,您可以修改 PCapLib 以启用它。例如:

    1. 创建一个抽象方法,返回您需要的所有数据包信息,并且每个类都必须实现它(TCP、UDP、ICMP 类),添加一些方法(例如接收源/目标 IP、源/目标端口等)。主要思想是使用多态性。

    2. 修改 PacketBuilder.Build 以接受这些参数。

    【讨论】:

    • 首选整数是什么意思?
    • @MikeMaggy 我的意思是:使用整数处理 IP 是更安全、更快捷的方式。 IP 地址具有 32 位信息,因此您可以将 IP 地址表示为整数。字符串太灵活了,例如:“127.0.0.1”与“127.0.0.1”不同。即使是空格也可能导致错误。在底层,比较整数比比较字符串要快。
    • 好吧,但是如果数据包是 TCP、UDP 等,我关于更改数据包 ip 的问题呢?
    【解决方案2】:

    您可以通过检查 EthernetDatagram.EtherType 字段来检查 EthernetDatagram 是否包含 VLAN 数据报。

    如果是这样,您应该通过以下方式进入您的 IPv4 层

    packet.Ethernet.VLanTaggedFrame.IpV4
    

    【讨论】:

      猜你喜欢
      • 2018-05-19
      • 2012-03-01
      • 2012-02-09
      • 2010-12-10
      • 2017-08-25
      • 1970-01-01
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多