Setting ControlBits

Jan 26, 2011 at 6:34 PM

Hello,
can you tell me how can I set ACK flag in sending packet? I'm sending packets in first application, second application receives it. I want to send acknowledgment to inform first application about successful delivery. I'm creating all necessary layers (ethernet, ip, tcp), i have read documentation but no idea how to set it.
Thanks in advance,
Maciek

Coordinator
Jan 28, 2011 at 5:06 PM

Hi Maciek,

 

TcpLayer has a property called ControlBits.

It's a Flags enum that has Acknowledgment value.

You can set ACK for example by doing:

 

TcpLayer tcpLayer = new TcpLayer();

tcpLayer.ControlBits = TcpControlBits.Acknowledgment;

 

Boaz.

Jan 29, 2011 at 12:56 AM
Edited Jan 29, 2011 at 1:08 AM

Thank you so much for your answer. It was very helpful. Just one more question. How can I increase Sequence Number and ACK Number? I have something like that:

 

while (true)
{
...
tcplayer.SequenceNumber = (uint)i;
AcknowledgmentNumber = (uint)k;
i++; k++;
}

 

Variable "i"/"k" should be increased in this loop therefore SequenceNumber/ACK Number. Wireshark informs that every packet, except first, is Retransmission.

Regards,
Maciek

Coordinator
Jan 29, 2011 at 8:53 AM

I'm not sure how Wireshark decides if two packets are retransmission.

Check with Wireshark the sequence number and ack number of the packets.

 

Boaz.

Jan 29, 2011 at 1:37 PM

I solved problem with sequence number and ack number, but still every packet is treated as retransmission and TCP Zero Window by Wireshark. This is how I'm creating packet:

                // Set mac source
                MacAddress source = new MacAddress(sourceMAC);

         
                // Create the packets layers

                // Ethernet Layer
                EthernetLayer ethernetLayer = new EthernetLayer
                {
                    Source = source,
                };
                
                // IPv4 Layer
                IpV4Layer ipV4Layer = new IpV4Layer
                {
                    Source = new IpV4Address("192.168.1.102"),
                    Ttl = 128,
                };

                // TCP Layer
                TcpLayer tcplayer = new TcpLayer();
                tcplayer.SourcePort = 8000;

                // Set IPv4 parameters
ipV4Layer.Destination = new IpV4Address(destinationIP);
tcplayer.SequenceNumber = (uint)i;

                PacketBuilder builder = new PacketBuilder(ethernetLayer, ipV4Layer, tcplayer);

// Build the packet Packet packet = builder.Build(DateTime.Now); // Send down the packet communicator.SendPacket(packet);

Maciek.

Coordinator
Jan 29, 2011 at 4:11 PM

You should set the other fields of TcpLayer.

Jan 29, 2011 at 11:46 PM
Edited Jan 29, 2011 at 11:49 PM

Thank you for your answer. Now only packets with payload are treated as Retransmission. Packets with payload length = 0 are "normal". Maybe I missed some field again? Is it possible to set multiple flags (for example ACK and PSH)?

 

TcpLayer tcplayer = new TcpLayer();
tcplayer.SourcePort = sourcePort;
tcplayer.DestinationPort = destPort;
tcplayer.SequenceNumber = (uint)i;
tcplayer.Window = (ushort)45192;
tcplayer.ControlBits = TcpControlBits.Push; tcplayer.ControlBits = TcpControlBits.Acknowledgment;

In this case Acknowledgment overwrites Push.

Maciek.

 

Coordinator
Jan 30, 2011 at 12:25 PM

You can set multiple flags by using bitwise or (like any other C# flags enum):

tcplayer.ControlBits = TcpControlBits.Push | TcpControlBits.Acknowledgment;

 

I'm not sure how Wireshark identifies retransmissions.

Maybe you gave an overlapping sequence numbers (remember that sequence number should be incremented by the number of bytes in the TCP payload, and +1 for SYNs and FINs).

 

Boaz.