Criando pacotes de rede utilizando a biblioteca C# SharpPcap

Neste paper, vamos explorar como criar pacotes de rede utilizando a biblioteca SharpPcap em C#. A SharpPcap é uma biblioteca multiplataforma (Windows,Linux) poderosa que permite capturar e enviar pacotes de rede de forma fácil e eficiente. Antes de começar recomendo que você tenha conhecimentos sobre redes, especialmente o modelo TCP/IP.

Criando o projeto

Para começar, crie um novo projeto C# do tipo Console. Use seu editor/IDE de preferência.

dotnet new console --name PacketBuilding -o src

dotnet new sln -n PacketBuilding

dotnet sln add src/PacketBuilding.csproj

Instalando a biblioteca SharpPcap

⚠️ Atenção: se você estiver usando Linux/Unix-like será necessário instalar a biblioteca libpcap-dev

Para instalar a biblioteca SharpPcap, você pode usar o NuGet. Execute o seguinte comando no terminal dentro do diretório do seu projeto:

dotnet add package SharpPcap

O mesmo processo para o PacketDotNet.

dotnet add package PacketDotNet

Criando EthernetPacket, TcpPacket e IPv4Packet

O EthernetPacket, TcpPacket e IPv4Packet são classes da biblioteca PacketDotNet, onde cada uma representa um nível do modelo do modelo TCP/IP.

Neste exemplo vamos fazer um Three-Way-Handshake (Aperto de mãos) que consiste em três etapas:

  1. O cliente envia um pacote SYN para o servidor.
  2. O servidor responde com um pacote SYN-ACK.
  3. O cliente envia um pacote ACK para o servidor.

Criando a estrutura do pacote Ethernet:

                
using PacketDotNet;
using SharpPcap;

var ethernetPacket = new EthernetPacket(
    PhysicalAddress.Parse("00-11-22-33-44-55"), // Endereço MAC de origem
    PhysicalAddress.Parse("66-77-88-99-AA-BB"), // Endereço MAC de destino
    EthernetType.IPv4 // Tipo de protocolo, no caso vamos usar o IPv4
);
                
            

Criando a estrutura do pacote IPv4:

                
var ipPacket = new IPv4Packet(IPAddress.Parse("IP_ORIGEM"), IPAddress.Parse("IP_DESTINO")) {
    Version = 4, // Versão do IP
    Protocol = ProtocolType.Tcp, // Protocolo TCP
    Ttl = 64 // Time to Live
};
                
            

Criando a estrutura do pacote TCP:

                
var random = new Random();
var randomPort = (ushort)random.Next(1024, 65535);
ushort destPort = 80;

var tcpPacket = new TcpPacket(randomPort, destPort);
tcpPacket.Synchronize = true; // Sinaliza o pacote SYN
tcpPacket.SequenceNumber = (uint)random.Next(); // Número de sequência aleatório
                
            

Agora que temos os pacotes Ethernet, IPv4 e TCP, podemos empacotá-los juntos:

                
ipPacket.PayloadPacket = tcpPacket;
ethernetPacket.PayloadPacket = ipPacket;
ethernetPacket.UpdateCalculatedValues(); // Calcular checksum
                
            

Enviando o pacote

Para enviar o pacote, você precisará de uma interface de rede. Você pode listar as interfaces disponíveis usando o seguinte código:

                
var devices = CaptureDeviceList.Instance;
foreach (var device in devices)
{
    Console.WriteLine($"{device.Name} - {device.Description}");
}
                
            

Depois de escolher a interface, você pode enviar o pacote usando o seguinte código:

                
using (var device = devices[0]) // Substitua pelo índice da interface desejada
{
    device.Open(DeviceMode.Promiscuous, 1000); // Abrir a interface em modo promíscuo
    device.SendPacket(ethernetPacket); // Enviar o pacote Ethernet
    device.Close(); // Fechar a interface
}
                
            

Conclusão

Se você tiver alguma dúvida você pode consultar TCP/IP GeeksForGeeks Doc