I am currently programming with libnet and pcap and I captured the following TCP handshake, but the server doesn't except the last step of the handshake and responds with a reset.
x.x.x.1 = client (packets sent using libnet)
x.x.x.2 = server (packets sent by kernel)
Is the third step of the handshake valid? The client has the servers seq.number+1 as acknowledgement since that is the next byte that he expects. Is there any reason why a reset is sent by the server based on this tcpdump? If not I have to look elsewhere.
x.x.x.1.y > x.x.x.2.y SYN, seq 100, length 0 win 65535
x.x.x.2.y > x.x.x.1.y SYN|ACK, seq 145411296, ack 101, length 0, options [mss 1460], win 14600
x.x.x.1.y > x.x.x.2.y SYN|ACK, seq 101, ack 145411297, length 0, win 65535
x.x.x.2.y > x.x.x.1.y RST, seq 145411297, length 0, win 0
Also, what is the time before a connections times out?
Nevermind, I found it.
The third step of the handshake should be an ACK not a SYN|ACK.
Related
How does tcp protocol (of an established connection) respond to a package with an ack number higher than the largest sequence number sent. That is, the other party tells that it has received bytes that the other end of the connection have not sent.
How does tcp protocol respond to that?
I know that control bits in tcp define the flags of TCP connection like SYN, FIN, ACK. But from my network traffic sometimes for some packets control bits are 0 (not-set).
What does this behaviour mean?
Those are flags of a TCP segment, not connection.
When a flag bit isn't set that indicates the absence of the meaning and behavior defined for the corresponding flag.
It means ACK and only ACK flag is set. RFC says ACK is 16, however it's only 16 when used in combination with another flag e.g. SYN/ACK (18), FIN/ACK (17). Flags value 0 could also indicate a 'null' scan.
If you see a flow record with value 2 and there are 8 packets in it, that means there are both SYN packet(s) and ACK packets.
If you see 18 and there are more than 1 packet in the flow that means there is at least one SYN/ACK and the rest are ACK.
To illustrate a TCP self connect example
nc -p 9987 127.0.0.1 9987
tcpdump captured the connection establishment
17:52:33.980137 IP 127.0.0.1.9987 > 127.0.0.1.9987: Flags [S], seq 4215993872, win 43690, options [mss 65495,sackOK,TS val 10050427 ecr 0,nop,wscale 7], length 0
17:52:33.980162 IP 127.0.0.1.9987 > 127.0.0.1.9987: Flags [S.], seq 4215993872, ack 4215993873, win 43690, options [mss 65495,sackOK,TS val 10050427 ecr 10050427,nop,wscale 7], length 0
17:52:33.980174 IP 127.0.0.1.9987 > 127.0.0.1.9987: Flags [.], ack 1, win 342, options [nop,nop,TS val 10050427 ecr 10050427], length 0
It was just like the normal TCP establishment, but the dst addr and src addr are the same.
Recall the TCP simultaneous open [ref: TCP/IP Illustrated, Volume 1, Figure 18.17 and Figure 18.18]
Next, recall the TCP state transition diagram
For the self connect situation, the TCP state transition should be:
send SYN to the dst, CLOSE -> SYN_SENT
receive SYN (from self), send SYN+ACK to dst, SYN_SENT -> SYN_RCVD
receive SYN+ACK (from self), SYN_RCVD -> ESTABLISHED
Question 1
The procedure is totally different(shown by tcpdump) between self connect and simultaneous open. Is there anything I missed?
Question 2
receive SYN+ACK (from self), SYN_RCVD -> ESTABLISHED
This transition is not presented in the TCP state transition diagram. How to explain it?
No, it's not a simultaneous open. Simultaneous open is something that was theorized and written into the standard, but never happens in practice.
In a simultaneous open, the theory is that two hosts simultaneously (or near enough in that each end has not seen the initial SYN of the other side before attempting to open a connection) attempt to establish a connection, but with special conditions.
Host A opens from port X connecting to port Y on B.
Host B opens from port Y to port X on A.
In this case, you will see what appears to be a four way handshake. If you'd like to prove to yourself that this works, you can use Scapy to try it out. Here is a Scapy script that you can run on a host. You must use iptables to disabled outbound RST packets from the host or it will fail
If you run that script and then connect from any other client host, you will see a four way handshake in action!
The below screenshot shows the relevant packets I am analysing, which are independent from the rest of the network traffic.
I know that this is malformed network traffic, however I am confused as to why the correct values should be [RST,ACK] Seq = 1 Ack = 1 ... in oppose to the values seen in the screen shot for packet 8.
Any help would be appreciated, as most of the online documentation and explanations I have read, have not given a concrete explanation.
According to RFC 793, page 37:
In the SYN-State (The sender sent a segment with SYN flag, packet 7), The received RST segment (packet 8) is acceptable if the ACK field acknowledges the SYN.
So, packet 8 is malformed and not acceptable for sender of SYN segment, because ACK field is here 0 (relative) instead of 1.
I'm confused about the ACK and SEQ numbers in TCP packets right after the 3-way-handshake. I thought the ACK number is the next expected SEQ number.
So when I analyse a TCP connection in Wireshark it says
TCP SYN with SEQ=0
TCP SYN ACK with SEQ 0, ACK=1 (clear, server expects SEQ 1 in next packet)
TCP ACK with SEQ 1, ACK=1 (clear, sender expects SEQ 1 in next packet)
HTTP Request: TCP PSH ACK with SEQ 1, ACK=1
The last line is unclear. I would say the sender expects SEQ=2 next, so it should be ACK=2? There was already a packet with SEQ=1 from the server, why does the sender want another one?
Can someone explain this to me?
Well, in the handshake the client receives only one packet from the server: SEQ=0 and ACK=1. With this information, the server tells the client 'I am waiting for a packet with SEQ=1 now'. You got this right.
Now, in the last part of the handshake the client sends a SEQ=1 and ACK=1, what basically means the same thing as from the server: 'I am waiting for your packet with SEQ=1 now'
But: After a TCP handshake, the client will usually not wait for this packet to be acked, but rather send the first data packets already (in fact, data may already be contained within the last packet of the handshake - I assume this is the case in your example, because the HTTP request has the same SEQ as the last handshake packet). So any next packet again has ACK=1. But why? It again says 'I am waiting for a packet with SEQ=1 from you'. And this completely makes sense: The last packet the client received from the server had SEQ=0 (in the handshake). Also keep in mind, that both client and server have independent SEQs. That means, that the client could send 100 packets. As long as the server did not send one, the client would still be waiting for ACK=1, because the last packet he received from the server hat SEQ=0
Another Edit:
To really understand what is going on, you might want to choose an example with different beginning SEQs (I already wrote it, SEQs of server and client are independent):
Client -> SYN, SEQ=100
Client <- SYN, ACK, SEQ=700, ACK=101 <- Server
Client -> ACK = 701, SEQ=101 [50 Bytes of data]
Client -> ACK = 701 [Again, didn't receive sth from server yet], SEQ = 151
Acknowledgment number (32 bits) – if the ACK flag is set then the value of this field is the next sequence number that the receiver is expecting. This acknowledges receipt of all prior bytes (if any). The first ACK sent by each end acknowledges the other end's initial sequence number itself, but no data.
So they just acknowledge where they should start from.
TCP on Wikipedia
The answer to your question is actually quite simple. I can see that you have no problem understanding the three-way handshake procedure I'll assume that you already know client and server count the Sequence Number separately and independently, but please notice: a pure ACK packet does not contribute to Sequence Number:
SEG.LEN = the number of octets occupied by the data in the segment
(counting SYN and FIN)
See RFC 793
Therefore, the second packet [SYN, ACK] does increase the Sequence Number by 1, but the third packet [ACK] does not affect the Sequence Number, which is the reason why next packet still has Seq=1.
I'll show you a sample TCP connection in SMTP to further illustrate it:
Client -> Server: [SYN] Seq=0 Len=0
Server -> Client: [SYN, ACK] Seq=0 Ack=1 Len=0
Client -> Server: [ACK] Seq=1 Ack=1 Len=0
Server -> Client: [PSH, ACK] Seq=1 Ack=1 Len=46
Client -> Server: [ACK] Seq=1 Ack=47 Len=0
Client -> Server: [PSH, ACK] Seq=1 Ack=47 Len=24
Server -> Client: [PSH, ACK] Seq=47 Ack=25 Len=63
You can see that after the connection was made, the Client actually sent three consecutive packets with Seq=1! This is because the pure ACK packet does not increase the Sequence Number, which kind of makes sense because you're not transferring real data.
In a summary, the Sequence Number does not always increase after you sent off packets. As a rule of thumb, you just need to look at the len and check SYN FIN flags to determine whether the Sequence Number should be increased.