tcp_packet.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. """
  2. Структура TCP сегмента:
  3. Слово 1
  4. SRC (16 бит) номер порта источника
  5. DST (16 бит) номер порта назначения
  6. Слово 2
  7. SEQ (32 бита) позиционный номер, место первого байта данных сегмента в
  8. потоке данных от источника до получателя.
  9. Слово 3
  10. ACK (32 бита) квитанция
  11. Слово 4
  12. LEN (4 бита) длина заголовка
  13. reserv (6 бит)
  14. FLAGS (6 бит) флаги
  15. WND (16 бит) размер окна приема
  16. """
  17. import socket
  18. import struct
  19. import array
  20. class TCPPacket:
  21. _srcip = None
  22. _dstip = None
  23. SRC = 0 # номер порта источника
  24. DST = 0
  25. SEQ = 0 # позиционный номер
  26. ACK = 0 # квитанция
  27. LEN = 0 # длина заголовка
  28. # flags
  29. f_URG = 0
  30. f_ACK = 0
  31. f_PSH = 0
  32. f_RST = 0
  33. f_SYN = 0
  34. f_FIN = 0
  35. WND = 0 # размер окна приема
  36. CHK = 0 # контрольная сумма
  37. URG = 0 # указатель границы срочный данных
  38. OPT = '' # опции
  39. DATA = "" # данные
  40. def __init__(self) -> None:
  41. print("Create TCP packet instance")
  42. def set_data(self, data):
  43. self.DATA = data
  44. def set_ip(self, src, dst):
  45. self._srcip = src
  46. self._dstip = dst
  47. def to_hex_string(self):
  48. tcp_flags = self.f_FIN + (self.f_SYN << 1) + (self.f_RST << 2) + \
  49. (self.f_PSH << 3) + (self.f_ACK << 4) + (self.f_URG << 5)
  50. header = struct.pack('!HHLLBBHHH', self.SRC, self.DST, self.SEQ, self.ACK,
  51. (self.LEN << 4) + 0, tcp_flags, self.WND, self.CHK, self.URG)
  52. # calculate data length
  53. data_len = 0
  54. if(self.DATA != None):
  55. data_len = len(self.DATA)
  56. # create pseudo TCP packet
  57. psh = struct.pack('!4s4sBBH',
  58. socket.inet_aton(self._srcip), # type: ignore
  59. socket.inet_aton(self._dstip), 0, # type: ignore
  60. socket.IPPROTO_TCP,
  61. len(header) + data_len)
  62. psh = psh + header + bytes(self.DATA, 'utf-8')
  63. crc = self.crc(psh)
  64. return struct.pack('!HHLLBBH', self.SRC, self.DST, self.SEQ, self.ACK, \
  65. (self.LEN << 4) + 0, tcp_flags, self.WND) + \
  66. struct.pack('H', crc) + struct.pack('!H', self.URG) + \
  67. bytes(self.DATA, 'utf-8')
  68. def crc(self, data: bytes):
  69. if len(data)%2 != 0:
  70. data += b'\0'
  71. res = sum(array.array("H", data))
  72. res = (res >> 16) + (res & 0xffff)
  73. res += res >> 16
  74. return (~res) & 0xffff
  75. @staticmethod
  76. def get_falgs_from_byte(data):
  77. flags = [0,0,0,0,0,0]
  78. flags[0] = (data >> 5) & 1
  79. flags[1] = data >> 4 & 1
  80. flags[2] = data >> 3 & 1
  81. flags[3] = data >> 2 & 1
  82. flags[4] = data >> 1 & 1
  83. flags[5] = data & 1
  84. return (flags[0], flags[1], flags[2], flags[3], flags[4], flags[5])
  85. def __str__(self):
  86. s = ""
  87. s += "TCP Segment"
  88. s += "\tSource Port: {}, Destination Port: {}\n".format(self.SRC, self.DST)
  89. s += "\tSequence: {}, Acknowledgement: {}\n".format(self.SEQ, self.ACK)
  90. s += "\tFlags\n"
  91. s += "\t\tURG: {}, ACK: {}, PSH: {}\n".format(self.f_URG, self.f_ACK, self.f_PSH)
  92. s += "\t\tRST: {}, SYN: {}, FIN: {}\n".format(self.f_RST, self.f_SYN, self.f_FIN)
  93. s += "\tHeader Length: {}, Window Size: {}\n".format(self.LEN, self.WND)
  94. # Other parameters
  95. s += "Over parameters\n"
  96. s += "\t\tSRC ip: {}, DST ip: {}\n".format(self._srcip, self._dstip)
  97. return s
  98. def main():
  99. pack = TCPPacket()
  100. print(pack)
  101. if __name__ == "__main__":
  102. main()