Is it true that the Acknowledgment Number (please note I'm not talking about the ACK flag here) is set to 0 when a client initiates the 3-way TCP handshake by sending its initial packet?
I have a TCP trace file and I used the pcap library in C to print out specific information for every packet. What I noticed was that the Acknowledgment Number of the very first packet in a connection is always set to 0. Could I use that as criteria in identifying the first packet of a TCP session?
If not that, what other criteria can I use to identify a given packet as being the first one sent by the web client? Simply looking at the SYN flag won't work since when the server responds to the initial request by the client, it will also set its SYN flag.
The sequence number will have a random value, but it is completely normal behavior for the acknowledgement (which you ask about) number field to contain 32 bits of zeroes in it.
This isn't to say that it can't contain data. You rightly distinguish the ACK flag from the acknowledgement number. The actual meaning of the flag is to signal that the value in the acknowledgement number field is valid. Since it would be cleared on the initial SYN, there is no such claim. As such, it can contain absolutely anything, though again, normal behavior is zero.
As to your question in distinguishing the initial SYN from the response, the response to a properly formed initial SYN by a normal IP stack will be SYN-ACK. So, while the SYN will be set, the ACK will also be set. To distinguish one from the other the better practice would be to look at the TCP code bits field rather than the sequence numbers unless you are trying to do some kind of anomaly detection.
Related
I processed a number of pcap files, extracted individual packets and arranged them in a per-flow data structure (flow table) as a list of packets. Now, since packets may arrive out-of-order, I need to re-order them accordingly. My main criteria is sequence number field from then TCP header; I guess this is the only way to re-order TCP packets?
When extracting packets from pcap files I already read SEQ value and stored in my per-packet structure, as well as next (expected) sequence value, as pkt->seq + TCP_segment_size.
Now, what would be the right approach to do this? I could sort the list of packets in a flow per SEQ value, but it will be very slow.
Also: do I need to obtain the ISN (initial sequence number) before start re-ordering? (basically the 1st packet with SYN bit set will have ISN in seq field of TCP header) The problem is that such packet may be missing (example: started capturing after handshake completed.)
How is re-ordering normally done?
I am implementing a client/server echo program using the Stop-and-Wait protocol. Part of the implementation is to randomly introduce drops from the server. I am actually randomly dropping ACKs as well as FRAMEs. A side effect of this is the introduction of a corner case:
If the last ACK from the server is dropped, both client and server end up in a "send" mode. This happens because the server doesn't know the last ACK was dropped, and from its perspective, everything worked and it now should echo back everything the client sent to it.
The client, on the other hand, doesn't know if the last FRAME was dropped or if just the ACK was dropped, so it tries to resend the last FRAME.
I could see this being solved by the use of a FIN or something -- basically an extra ACK going the opposite direction when both sides think transmission is complete. However, I want to conform to the expected approach for Stop-and-Wait.
How should Stop-and-Wait handle this case?
One way to handle this situation is to have a one-bit sequence number included in every frame. Every time you send a frame and receive an ACK, you flip the bit for the next frame. If you send a frame, don't receive an ACK, and have to retransmit the frame, you resend it with the same sequence bit.
At the receiver, if you receive two (or more) frames in a row with the same sequence bit, you know it's a retransmission, so you can resend the ACK but ignore the frame, since you've already acted on it.
Don't bother trying to acknowledge acknowledgements. You just run into the same problem where the network might drop the ACK for the ACK.
I am programming a gateway which one of the functionality is to destroy connections when enough packets have been exchanged. I would like to know how to properly form RST packets to send to both the client and server to terminate the connection.
To test this, I use ftp connections/sessions. Right now, I am seeing that when I send the RST packets, the client endlessly replies with SYN packets, while the server simply continues the datastream with ACK packets. Note that after I decide to destroy the connection, I block the traffic between both ends.
I am thinking there may be something wrong with the way I handle my SEQ and ACK numbers. I have not been able to find ressources to explain what to do with the SEQ and ACK numbers when sending a RST packet specifically. Right now, I set the SEQ to a new random number (with rand()) and set the ACK to 0 (since I am not using the ACK flag). I invert the source address with destination address and source port with destination port, and have seen that I correctly calculate checksums.
I seems like both the client and server do not accept the termination.
I don't know what 'resources' you are using, but this seems to be completely covered under 'Reset Generation' in section 3.4 of RFC 793. The RST has sequence number zero and the ACK field is set to the incoming ACK field plus the length, etc as described there several times.
I am writing a program that uses libpcap to capture packets and reassemble a TCP stream. My program simply monitors the traffic and so I have no control over the reception and transmittal of packets. My program disregards all non TCP/IP traffic.
I calculate the next expected sequence number from the ISN and then the successive SEQ numbers. I have it set up so that every TCP connection is uniquely identified by a tuple made up of the source IP, source port, dest IP, and dest port. Everything goes swimmingly until I receive a packet that has a sequence number different than what I am expecting. I have uploaded screen shots to help illustrate what I am describing here.
My questions are:
1. Where is the data that was in the "lost" packet?
2. How does the SEQ number order recover from this situation?
3. What can I do to handle these occurrences.
Please remember; however, I am not writing a program that adheres to TCP. I am writing a program that passively monitors network traffic for TCP streams and attempts to save the raw data to disk, and I am confused as to why the above state situation happens and how I can program to handle it.
Thank you
Where is the data that was in the "lost" packet?
It got dropped by someone
It got lost on the way (wrong detour) and will arrive later
How does the SEQ number order recover from this situation
The receiver notices the segment is out of sequence and doesn't send it to the application, thereby fulfilling its contract: in-order reliable byte stream. Now, what actually happens to get the missing piece is quite intricate and varies from stack to stack. In a nutshell the stack waits for the missing piece to arrive.
The receiver can throw away out-of-sequence segments or it can queue them in a reassembly queue
The receiver can wait for the missing segment to arrive or it can immediately send the ACK it already sent before. Duplicate ACKs will alert the peer something is wrong (look for Fast Retransmit)
When sending acknowledgments the TCP can inform the peer some segments arrived successfully - they're just out of sequence (SACK)
What can I do to handle these occurrences
You can't do anything since you're only monitoring. You could probably get more insight into what is really happening if you also captured the response traffic.
Depending on the window-size of the current TCP connection, if the new packet fits within the receiving window (multi-packet buffer) it will be entered into the receiving queue (and reordered for ordered delivery to protocol clients).
If the sequence number is larger than the maximum for the current window, the packet gets rejected.
See also section 4.4.2 (INPUT PACKET HANDLER) in RFC 675
I'm writing a windows driver (of course in c and I'm in kernel mode) and I'd like to open a tcp socket from the outside specifying the sequence number the first SYN packet should have.
I tried modifying the packet filtering it with Windows Filtering Platform, but of course it doesn't work because the stack think that the correct number is the original one and the recipient's stack think that the correct one is modified one.
I'm looking somethink like:
OpenSocket(..., UINT32 seqNum, UINT16 winSize)
or anything equivalent.
There is a way to do that?
Thanks,
Marco
Seems like a strange thing to be doing, but if your filter can modify both incoming and outgoing packets then it can fix the sequence number in both directions.
Just figure out the offset from the orignal sequence number. Then you can add it to the sequence number for outgoing packets and subtract it from the acknowledgment numbers for incoming packets.
Each side of the conversation gets exactly what they expect, even though they disagree on what is expected.