__init__.py 2.9 KB

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