iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
0

在Day13和Day14介紹了TCP的封包結構,TCP是連接導向的協議,所以在建立連線前需要和對方確認和對方的通信收發是正常的,在斷開連接也需要和對方確認沒有額外需要傳輸的封包才會斷開連線

作為發送raw封包的第一個實作,當然從最難的TCP開始囉!會了TCP的發送,同時也會了底下第二層和第三層header的封裝,所以拆分很多天,盡量講的鉅細靡遺

在發送tcp的封包前,先看一下第二層、第三層和tcp的header怎麼封裝,分別為_buildEthHeader()_buildIPHeader()

def _buildEthHeader(self):
        dMAC = '02:42:ac:11:00:05' # 要根據目的地的Mac address設定
        dMAC = binascii.unhexlify(str.encode(''.join((dMAC.split(':')))))
        eth_header = struct.pack('!6s6sH' , dMAC, self.mac, socket.htons(8))
        return eth_header
def _buildIPHeader(self):
        pktID = 123 # 隨便設定packet id
        IHL_VERSION, TYPE_OF_SERVICE, total_len, FRAGMENT_STATUS, TIME_TO_LIVE, PROTOCOL, check_sum_of_hdr, src_IP,dest_IP = \
                69, 0, 40, 16384, 64, 6, 0, socket.inet_aton(socket.gethostbyname(socket.gethostname())), socket.inet_aton(self.dip)
        ip_header = struct.pack('!BBHHHBBH4s4s', IHL_VERSION, TYPE_OF_SERVICE, total_len, pktID, FRAGMENT_STATUS, TIME_TO_LIVE, PROTOCOL, check_sum_of_hdr, src_IP,dest_IP)
        check_sum_of_hdr = getIPChecksum(ip_header)
        ip_header = struct.pack('!BBHHHBBH4s4s', IHL_VERSION, TYPE_OF_SERVICE, total_len, pktID, FRAGMENT_STATUS, TIME_TO_LIVE, PROTOCOL, check_sum_of_hdr, src_IP,dest_IP)

        return ip_header
def _buildTCPHeader(self, tcp_len, seq, ack_num, flags, window): # 其中,seq, ack_num,
flags這三個參數最重要
    self.seq = seq
    self.ack_num = ack_num

    src_IP = socket.inet_aton(self.sip)
    dest_IP = socket.inet_aton(self.dip)

    src_port, dest_port,  offset, checksum, urgent_ptr = \
            self.sport, self.dport, tcp_len << 4, 0, 0
    tcp_header = struct.pack('!HHIIBBHHH' , src_port, dest_port, self.seq, self.ack_num, offset, flags, window, checksum, urgent_ptr)
    pseudo_hdr = struct.pack('!4s4sBBH', src_IP, dest_IP,0 , socket.IPPROTO_TCP, len(tcp_header))
    checksum = getTCPChecksum(pseudo_hdr + tcp_header)
    tcp_header = tcp_header[:16] + struct.pack('H', checksum) + tcp_header[18:]

    return tcp_header

有了這兩個函數,那麼建構tcp的封包如下

packet = _buildEthHeader() + _buildIPHeader() + _buildTCPHeader() + data
sock.send(packet)

接下來講如何利用這三個函數建立三方交握的可靠連接

完整的tcp三方交握和四向揮手程式碼可以看這裡
https://gist.github.com/kaichiachen/283f1b57e517f9ed558de6c2d15daf62


上一篇
Day20 Checksum如何保證封包正確以及潛在危害
下一篇
Day22 自幹TCP三向交握(2)
系列文
那些年還給老師的TCP/IP五層結構 - 用Python進行網路封包分析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言