I'm working on a project and need to print out TCP sequence number and TCP ack number from the TCP header. Below is what I have done
ip = (struct iphdr*) buffer; //buffer is used to store the packet that I received
tcp = (struct tcphdr*) (buffer+(4*ip->ihl));
printf ("TCP sequence number = %d\n",ntohl(tcp->seq));
printf ("TCP ack number = %d\n",ntohl(tcp->ack_seq));
To ensure that I receive the packet correctly, I also print other information such as ip->saddr, tcp->source etc.. I have the same numbers as reported by Wireshark.
However, the numbers I printed out for sequence number and ack number are not matched. I got very big numbers (don't make any sense) for those two while Wireshark reports numbers that make sense such as Seq =1, Ack=1 or Seq=1, Ack=8, etc..
I noticed that next to sequence number and ack number reported in wireshark it says "relative sequence number" and "relative ack number" respectively. So I guess the numbers Wireshark reports are just relative numbers to something else, and the numbers that I print out from TCP header are the actual numbers.
Nevertheless, I want to print something as Wireshark reports, is it possible to do it? If so, please show me
Appreciate all the help, and thank you in advance!
The Wireshark sequence and ack numbers are relative to the first packets in the TCP connection (SYN from client to server, SYN and ACK from server to client). So just record the actual sequence and ack numbers from those packets, and subtract those values from the actual values the packet you are printing.
For example, if the client sends its SYN with actual sequence number 100, then subtract 100 from the actual sequence values in the subsequent packets in that TCP connection. This will give the relative sequence number.
Related
I have made a simple program in C.
Currenty I am trying to establish TCP handshake between server and client.
So when I recieve [SYN] flag then I respond with [SYN+ACK] flags (along with any sequence number, so I am choosing it as zero) and any ACK number
And in code when I receive in server ACK flag from client in TCP handshake's final packet I send ACK flag along with my own chosen sequence number (any number) and ACK numebr = one incremented of received SYC packet's sequence number because no data has been transmitted from server.
But I am not getting any ACK packet. my client is keep sending SYN packets and my server keep responding with Syn +ACK packet.
I like to know are sequence numbers and acknowledgement number during TCP handshake process are irreverent so I can focus on other fields which may be why my client ignoring my SYN responded SYC+ACK packet like IP and tcp checksum. Or is there anything wrong with my sequence and acknowlegement number handling first
In addition I am using TUN device in Linux that I created from server program
TCP sequence and acknowledgement numbers are absolutely NOT irrelevant during handshake (or any time in TCP connection). In fact, TCP handshake is there so that the server and the client can learn each other's sequence numbers. Your packets are ignored because ACKs do not match.
The ACK number in SYNACK packet is the sequence number in first SYN + 1. And the ACK number in last ACK packet is the seq. in SYNACK packet + 1.
In addition to the standard, linked by #Barmar, you can use this picture (source)
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?
Is it normal that there will be no packet losses in a UDP client-server if both are on the same machine? I'm currently calculating packet loss by taking the difference between the bytes obtained from the sendto and recvfrom functions on the client side ? Am I doing something wrong ?
I would be very surprised if there was any packet loss in such a case. But on the other hand you use the wrong way to calculate any loss.
Remember that UDP is a packet oriented protocol, which means that what you send will be a packet, and what you receive will be a packet, and there will be no difference in the size of what you send and receive. If you send a 512-byte packet, the receiver will always receive the full 512-byte packet, or nothing at all.
That means you should count the number of times you call sendto, and compare the number of times that recvfrom returns with a packet.
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.
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.