2014-11-19 6 views
0

В моем приложении я использую Pcap.net библиотеки DLL и изменения пакетов IP следующим образом:Изменение пакета IP, используя Pcap.Net без знать заранее, если пакет TCP, UDP

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 packetpacket.Ethernet.IpV4.Protocol отличается от TCP, хотя пакет является TCP, и в этом случае я возвращаю null, каким-либо образом, как достичь своей цели, не зная заранее, что мой пакетный протокол?

ответ

0

PCap.NET lib был переписан из C lib и, насколько я проверял, это было не очень хорошо OO, поэтому вам нужно проверить пакеты с помощью условных операторов.

Вот исходный код: http://pcapdotnet.codeplex.com/SourceControl/latest#PcapDotNet/src/

Совет: Избегайте сравнения IP в качестве строки. Предпочитайте целое число (IPv4), безопаснее и быстрее.

// Пример: IPv4 Convertion

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

Вы можете создать интерфейс для абстрактной информации пакета, чтобы включить классы говорить друг с другом (Patterns Adapter Design), но рано или поздно вы должны обнаружить каждый тип пакета. В противном случае вы можете изменить PCapLib, чтобы включить его. Например:

  1. Создать абстрактный метод, которые возвращают все данные пакета вам нужно, и каждый класс должен реализовать (TCP, UDP, классы ICMP), добавив некоторые методы (например, получать источника/назначения IP, источник/порт назначения и т. д.). Основная идея - использовать полиморфизм.

  2. Изменить PacketBuilder.Build, чтобы принять эти параметры.

+0

Что и означает Предпочитают целое? –

+0

@MikeMaggy Я имел в виду: обрабатывать IP с помощью целого является более безопасным и быстрым способом. IP-адресация содержит 32 бита информации, поэтому вы можете выразить IP-адреса как целочисленные. Строки слишком гибкие, например: «127.0.0.1» отличается от «127.0.0.1». Даже пробелы могут привести к ошибкам. На низком уровне сравнение целых чисел происходит быстрее, чем сравнение строк. –

+0

Хорошо, что хорошо, но как насчет моего вопроса об изменении пакета ip без предварительного уведомления, если пакет TCP, UDP и т. Д.? –

0

Вы можете проверить, содержит ли EthernetDatagram дейтаграмму VLAN, проверив поле EthernetDatagram.EtherType.

Если это произойдет, вы должны добраться до IPv4 слоя, делая

packet.Ethernet.VLanTaggedFrame.IpV4