From 1f097564f377cbc25884d6c6760dc4cb9414e9f9 Mon Sep 17 00:00:00 2001 From: George Hughey Date: Sat, 23 Nov 2019 17:07:02 +0000 Subject: [PATCH] Added trace action --- actions/trace.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 actions/trace.py diff --git a/actions/trace.py b/actions/trace.py new file mode 100644 index 0000000..3d7af87 --- /dev/null +++ b/actions/trace.py @@ -0,0 +1,80 @@ +import socket +import time + +from scapy.config import conf + +from actions.action import Action +import actions.utils + + +class TraceAction(Action): + """ + The Trace Action is used to TTL probe/traceroute a censor. When the action fires, + it sends the captured packet with increasing ttls within a certain range + + TraceAction is an experimental action that is never used + in actual evolution + """ + def __init__(self, start_ttl=1, end_ttl=64, environment_id=None): + Action.__init__(self, "trace", "out") + self.terminal = True + self.branching = False + self.start_ttl = start_ttl + self.end_ttl = end_ttl + # Since running this action might take enough time that additional packets + # get generated, only allow this action to run once + self.ran = False + # Define a socket + self.socket = conf.L3socket(iface=actions.utils.get_interface()) + + def run(self, packet, logger): + """ + The trace action sends the captured packet repeatedly with increasing ttl probes + defined between the range of start_ttl to end_ttl. This is an experimental action, + and is not used for training. + """ + logger.debug(" - Starting Trace action") + + if not packet.haslayer("IP"): + logger.debug(" - Could not identify IP header to perform ttl trace") + return packet, None + + if self.ran: + logger.debug(" - trace action already ran. Dropping given traffic. To reset this action, restart the engine.") + return None, None + + self.ran = True + for ttl in range(self.start_ttl, self.end_ttl): + logger.debug(" - ttl=%d" % ttl) + packet.set("IP", "ttl", ttl) + logger.debug("Sending packet %s", str(packet)) + self.socket.send(packet.packet) + time.sleep(1) + + return None, None + + def __str__(self): + """ + Returns a string representation. + """ + s = Action.__str__(self) + s += "{%d:%d}" % (self.start_ttl, self.end_ttl) + return s + + def parse(self, string, logger): + """ + Parses a string representation for this object. + """ + try: + if string: + self.start_ttl, self.end_ttl = string.split(":") + self.start_ttl = int(self.start_ttl) + self.end_ttl = int(self.end_ttl) + if self.start_ttl > self.end_ttl: + logger.error("Cannot use a trace with a start ttl greater than end_ttl (%d > %d)" % (self.start_ttl, self.end_ttl)) + return False + except ValueError: + logger.exception("Cannot parse ttls from given data %s" % string) + return False + + return True