上一回說了這三個函數_buildEthHeader()、 _buildIPHeader()、 _buildTCPHeader(tcp_len, seq, ack_num, flags, window) 如何建立header,接下來說如何利用這三個函數完成三方交握,先複習一下三方交握的的過程
接下來程式碼有點多,建議打開https://gist.github.com/kaichiachen/283f1b57e517f9ed558de6c2d15daf62 配合著看
第一步,我們要從client發送syn,配合著程式裡的send_syn函數
packet = eth_header + ip_header + _buildTCPHeader(tcp_len=5, seq=0, ack_num=0, flags=2, window=29200)
sock.send(packet)
其中seq和ack_num可以隨意給,但是flags必須設定為2,代表2^1,一次方代表flags第二個參數SYN,然後tcp_len必須是5以下,如果有特殊的需求才會5以上,詳情可以差維基百科
第二步
立即監聽從server端發過來的ACK和SYN,如何收packet在前面已經講過,這部分先略過,只要記得判斷packet的時候,tcp裡header的flag必須是18,代表2^4 + 2^1,如果收到這個packet才有下一步
第三步
監聽到來自server端的ACK和SYN,要立即發送ACK回去,否則server端會一直發送直到timeout,此時,發送回去的ACK裡的ACK_NUM和SYN不能隨便亂設定了,必須根據server端傳過來的ACK_NUMS和SEQ,這裡傳回去的ACK_NUM和SEQ分別為server的SEQ+1和ACK_NUM
self.seq = server.ack_num
self.ack_num = server.seq+1
所以程式如下
packet = eth_header + ip_header + _buildTCPHeader(tcp_len=5, seq=server.ack_num, ack_num= server.seq+1, flags=16, window=29200)
sock.send(packet)
最後來實驗一下,我們在hostA上跑監聽tcp port=80的servernc -l 172.17.0.5 80
然後在router啟動我們的封包監聽scriptPython3 main.py
最後,在hostB上跑tcp的handshake,跑之前需要先把系統自動發出的RST flag封包給擋掉
iptables -t filter -I OUTPUT -p tcp --sport 20 --tcp-flags RST RST -j DROP
Python3 tcp.py
可以看到如下結果,代表我們成功自己實作了三方交握
2020-09-18 11:37:30 AM INFO Source Mac: 02:42:ac:11:00:02 Destination Mac: 02:42:ac:11:00:05 Protocol: IPv4 Version: 4 Type of Service: 0 Packet ID: 123 TTL: 64 Protocol: TCP Source IP: 172.17.0.2 Destination IP: 172.17.0.5
{'SRC_PORT': 20, 'DEST_PORT': 80, 'SEQ': 0, 'ACK_NUM': 0, 'Flags': '_,_,_,_,_,_,SYN,_', 'RESERVE': 0, 'TCP_LENGTH': 5, 'WINDOW': 29200, 'CHECKSUM': 58692, 'PTR': 0, 'data': b''}
------------------------
2020-09-18 11:37:30 AM INFO Source Mac: 02:42:ac:11:00:05 Destination Mac: 02:42:ac:11:00:02 Protocol: IPv4 Version: 4 Type of Service: 0 Packet ID: 0 TTL: 64 Protocol: TCP Source IP: 172.17.0.5 Destination IP: 172.17.0.2
{'SRC_PORT': 80, 'DEST_PORT': 20, 'SEQ': 692864110, 'ACK_NUM': 1, 'Flags': '_,_,_,ACK,_,_,SYN,_', 'RESERVE': 0, 'TCP_LENGTH': 6, 'WINDOW': 29200, 'CHECKSUM': 22600, 'PTR': 0, 'data': b''}
------------------------
2020-09-18 11:37:30 AM INFO Source Mac: 02:42:ac:11:00:02 Destination Mac: 02:42:ac:11:00:05 Protocol: IPv4 Version: 4 Type of Service: 0 Packet ID: 123 TTL: 64 Protocol: TCP Source IP: 172.17.0.2 Destination IP: 172.17.0.5
{'SRC_PORT': 20, 'DEST_PORT': 80, 'SEQ': 1, 'ACK_NUM': 692864111, 'Flags': '_,_,_,ACK,_,_,_,_', 'RESERVE': 0, 'TCP_LENGTH': 5, 'WINDOW': 29200, 'CHECKSUM': 30586, 'PTR': 0, 'data': b''}