0

Using the PCAP.NET library for Windows, I can build an ICMP reply packet according to the documentation:

'''

   private static Packet BuildIcmpPacket(string sourcemac, string destmac, string sourceip, string targetip,int id, int seq,byte[] payload)
    {
        EthernetLayer ethernetLayer =
            new EthernetLayer
            {
                Source = new MacAddress(destmac),
                Destination = new MacAddress(sourcemac),
                EtherType = EthernetType.None, // Will be filled automatically.
            };

        IpV4Layer ipV4Layer =
            new IpV4Layer
            {
                Source = new IpV4Address(targetip),
                CurrentDestination = new IpV4Address(sourceip),
                Fragmentation = IpV4Fragmentation.None,
                HeaderChecksum = null, // Will be filled automatically.
                Identification = 123,
                Options = IpV4Options.None,
                Protocol = null, // Will be filled automatically.
                Ttl = 100,
                TypeOfService = 0,
            };

        IcmpEchoReplyLayer icmpLayer =
            new IcmpEchoReplyLayer
            {
                Checksum = null, // Will be filled automatically.
                Identifier = (ushort)id,
                SequenceNumber = (ushort)seq,
                //Payload =  payload,
            };
        
        PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer);

        return builder.Build(DateTime.Now);
    }
    

'''

I supplied mac addresses and IP addresses for the Ethernet and IPV4 layers instead of the example defaults.

The packet builder works, and I can send it to the wire, but the requesting host doesn't recognize the replies (wireshark sees them, but the requests are tagged as 'no reply found').

I'm guessing the ID and Sequence fields need to be repeated in the reply (which I have supplied), but I can't add the payload from the ping request. I can read it with this snippet:

'''

communicator.ReceivePacket(out wpacket);
if (wpacket == null)continue;
EthernetDatagram edg = wpacket.Ethernet;
IpV4Datagram ipv4 = edg.IpV4;
IcmpEchoDatagram icmpdg = (IcmpEchoDatagram)ipv4.Icmp;
int ID = icmpdg.Identifier;
int SEQ = icmpdg.SequenceNumber;
byte[] payload = icmpdg.Payload.ToArray();

'''

but I don't see a way to add payload data to the reply. NOTE: This packet builder does work; once I added the ID and Sequence numbers to the reply the sending host sees it, but it complains about no data received. This is actually sufficient for my needs, but I would like to add the paylaod data to send a 'legitimate' ping reply back.

buzzard51
  • 1,372
  • 2
  • 23
  • 40

1 Answers1

0

I found the answer with a little more digging through example code on github:

The original code for BuildIcmpPacket() shown above built the packet with these layers:

PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer);
return builder.Build(DateTime.Now);

The payload is added to the final packet by simply adding a PayloadLayer. The buffer supplied for this payload ('payloadBuffer') is the one read from the ping request (above).

...
IcmpEchoReplyLayer icmpLayer =
    new IcmpEchoReplyLayer
    {
        Checksum = null, // Will be filled automatically.
        Identifier = (ushort)id,
        SequenceNumber = (ushort)seq,
    };
PayloadLayer payloadLayer = 
new PayloadLayer
{
    Data = new Datagram(payloadBuffer, 0, payloadBuffer.Length),
};

PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, icmpLayer,payloadLayer);
return builder.Build(DateTime.Now);

The ping reply now works as expected, and the sender is satisfied with the reply.

buzzard51
  • 1,372
  • 2
  • 23
  • 40