__init__.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import threading
  2. import socket
  3. import logging
  4. from random import getrandbits
  5. from time import sleep, time
  6. from multiprocessing.pool import ThreadPool
  7. from multiprocessing import Lock
  8. from threading import Thread
  9. from pprint import pprint
  10. class MassTraceroute:
  11. def __init__(self, socket_timeout, listener_timeout, threads, targets, maxhops):
  12. logging.info("Setting up class")
  13. self.wait = 0.2
  14. self.maxhops = maxhops + 1
  15. self.listener_timeout = listener_timeout
  16. self.socket_timeout = socket_timeout
  17. self.targets = targets
  18. self.threads = threads
  19. self.pool = ThreadPool(processes=self.threads)
  20. self.routes = dict()
  21. for target in self.targets:
  22. self.routes[target] = dict()
  23. logging.info("Creating listener socket")
  24. self.listener = self.init_listener()
  25. self.sources = dict()
  26. self.last_send = time()
  27. def main(self):
  28. logging.info("Starting listener thread")
  29. Thread(target=self.process_listener).start()
  30. logging.info("Starting sender thread")
  31. Thread(target=self.process_sender).start()
  32. def init_listener(self):
  33. listener = socket.socket(
  34. family=socket.AF_INET,
  35. type=socket.SOCK_RAW,
  36. proto=socket.IPPROTO_ICMP
  37. )
  38. listener.settimeout(self.listener_timeout)
  39. listener.bind(('', 0))
  40. return listener
  41. def process_listener(self):
  42. while((self.last_send + self.listener_timeout) > time()):
  43. logging.debug("Listening...")
  44. try:
  45. data, addr = self.listener.recvfrom(1024)
  46. except socket.error as e:
  47. logging.debug(e)
  48. pass
  49. srcport = int.from_bytes(data[48:50], byteorder="big")
  50. dstport = int.from_bytes(data[50:52], byteorder="big")
  51. logging.info("Got data from ip = {}, srcport = {}, dstport = {}, original target = {}, hop = {}".format(addr[0], srcport, dstport, self.sources[srcport]["ip"], self.sources[srcport][dstport]))
  52. if srcport in self.sources and dstport in self.sources[srcport]:
  53. hop = self.sources[srcport][dstport]
  54. ip = self.sources[srcport]["ip"]
  55. self.routes[ip][hop] = addr[0]
  56. logging.info(self.routes[ip][hop])
  57. else:
  58. logging.error("Received package with srcport or dstport non existsant?")
  59. pprint(self.routes)
  60. def process_sender(self):
  61. logging.info("Starting process_sender")
  62. #for target in self.targets:
  63. # self.send(target)
  64. self.pool.map(self.send, self.targets)
  65. def init_sender(self):
  66. sender = socket.socket(
  67. family=socket.AF_INET,
  68. type=socket.SOCK_DGRAM,
  69. proto=socket.IPPROTO_UDP
  70. )
  71. return sender
  72. def send(self, dstip):
  73. logging.info("Entering send()")
  74. sender = self.init_sender()
  75. while(True):
  76. srcport = getrandbits(16)
  77. if srcport not in self.sources:
  78. self.sources[srcport] = dict()
  79. self.sources[srcport]["ip"] = dstip
  80. break
  81. logging.info("Binding sending socket")
  82. sender.bind(('', srcport))
  83. for ttl in range(1, self.maxhops):
  84. sender.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
  85. dstport = getrandbits(16)
  86. while(True):
  87. dstport = getrandbits(16)
  88. if dstport not in self.sources[srcport]:
  89. self.sources[srcport][dstport] = ttl
  90. logging.debug("Saved ttl = {}, original ttl = {}, target = {}".format(self.sources[srcport][dstport], ttl, dstip))
  91. break
  92. logging.debug("Sending packet srcport = {}, dstport = {}, ttl = {}, dstip = {}".format(srcport, dstport, ttl, dstip))
  93. sender.sendto(b'', (dstip, dstport))
  94. self.last_send = time()
  95. sender.close()