PcapFile.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import hashlib
  2. import os.path
  3. import ID2TLib.libpcapreader as pr
  4. class PcapFile(object):
  5. def __init__(self, pcap_file_path: str):
  6. """
  7. Creates a new PcapFile associated to the PCAP file at pcap_file_path.
  8. :param pcap_file_path: The path to the PCAP file
  9. """
  10. self.pcap_file_path = pcap_file_path
  11. def merge_attack(self, attack_pcap_path: str):
  12. """
  13. Merges the loaded PCAP with the PCAP at attack_pcap_path.
  14. :param attack_pcap_path: The path to the PCAP file to merge with the PCAP at pcap_file_path
  15. :return: The file path of the resulting PCAP file
  16. """
  17. pcap = pr.pcap_processor(self.pcap_file_path, "False")
  18. file_out_path = pcap.merge_pcaps(attack_pcap_path)
  19. return file_out_path
  20. def merge_attack_into(self, attack_pcap_path: str, merged_out_path: str):
  21. """
  22. Merges the loaded PCAP with the PCAP at attack_pcap_path and stores the result in merged_out_path.
  23. :param attack_pcap_path: The path to the PCAP file to merge with the PCAP at pcap_file_path
  24. :param merged_out_path: The path to the output PCAP file
  25. :return: The file path of the resulting PCAP file
  26. """
  27. pcap = pr.pcap_processor(self.pcap_file_path, "False")
  28. file_out_path = pcap.merge_pcaps_into(attack_pcap_path, merged_out_path)
  29. return file_out_path
  30. def get_file_hash(self):
  31. """
  32. Returns the hash for the loaded PCAP file. The hash is calculated bsaed on:
  33. - the file size in bytes
  34. - the first 224*40000 bytes of the file
  35. :return: The hash for the PCAP file as string.
  36. """
  37. # Blocksize in bytes
  38. const_blocksize = 224
  39. # Number of blocks to read at beginning of file
  40. const_max_blocks_read = 40000
  41. # Initialize required variables
  42. hasher = hashlib.sha224()
  43. blocks_read = 0
  44. # Hash calculation
  45. with open(self.pcap_file_path, 'rb') as afile:
  46. # Add filename -> makes trouble when renaming the PCAP
  47. # hasher.update(afile.name.encode('utf-8'))
  48. # Add file's last modification date -> makes trouble when copying the PCAP
  49. # hasher.update(str(time.ctime(os.path.getmtime(self.pcap_file_path))).encode('utf-8'))
  50. # Add file size
  51. hasher.update(str(os.path.getsize(self.pcap_file_path)).encode('utf-8'))
  52. # Add max. first 40000 * 224 bytes = 8,5 MB of file
  53. buf = afile.read(const_blocksize)
  54. blocks_read += 1
  55. while len(buf) > 0 and blocks_read < const_max_blocks_read:
  56. hasher.update(buf)
  57. buf = afile.read(const_blocksize)
  58. blocks_read += 1
  59. return hasher.hexdigest()
  60. def get_db_path(self, root_directory: str = os.path.join(os.path.expanduser('~'), 'ID2T_data', 'db')):
  61. """
  62. Creates a path based on a hashed directory structure. Derives a hash code by the file's hash and derives
  63. thereof the database path.
  64. Code and idea based on:
  65. http://michaelandrews.typepad.com/the_technical_times/2009/10/creating-a-hashed-directory-structure.html
  66. :param root_directory: The root directory of the hashed directory structure (optional)
  67. :return: The full path to the database file
  68. """
  69. def hashcode(input: str):
  70. """
  71. Creates a hashcode of a string, based on Java's hashcode implementation.
  72. Code based on: http://garage.pimentech.net/libcommonPython_src_python_libcommon_javastringhashcode/
  73. :param input: The string the hashcode should be calculated from
  74. :return: The hashcode as string
  75. """
  76. h = 0
  77. for c in input:
  78. h = (31 * h + ord(c)) & 0xFFFFFFFF
  79. return ((h + 0x80000000) & 0xFFFFFFFF) - 0x80000000
  80. file_hash = self.get_file_hash()
  81. hashcode = hashcode(file_hash)
  82. mask = 255
  83. dir_first_level = hashcode & mask
  84. dir_second_level = (hashcode >> 8) & mask
  85. return os.path.join(root_directory, str(dir_first_level), str(dir_second_level), file_hash[0:12] + ".sqlite3")