def __gen_send( s, # type: SuperSocket x, # type: _PacketIterable inter=0, # type: int loop=0, # type: int count=None, # type: Optional[int] verbose=None, # type: Optional[int] realtime=False, # type: bool return_packets=False, # type: bool *args, # type: Any **kargs # type: Any ): # type: (...) -> Optional[PacketList] """ An internal function used by send/sendp to actually send the packets, implement the send logic... It will take care of iterating through the different packets """ if isinstance(x, str): x = conf.raw_layer(load=x) if not isinstance(x, Gen): x = SetGen(x) if verbose is None: verbose = conf.verb n = 0 if count is not None: loop = -count elif not loop: loop = -1 if return_packets: sent_packets = PacketList() try: while loop: dt0 = None for p in x: if realtime: ct = time.time() if dt0: st = dt0 + float(p.time) - ct if st > 0: time.sleep(st) else: dt0 = ct - float(p.time) s.send(p) if return_packets: sent_packets.append(p) n += 1 if verbose: os.write(1, b".") time.sleep(inter) if loop < 0: loop += 1 except KeyboardInterrupt: pass if verbose: print("\nSent %i packets." % n) if return_packets: return sent_packets return None
def __gen_send(s, x, inter=0, loop=0, count=None, verbose=None, realtime=None, return_packets=False, *args, **kargs): # noqa: E501 if isinstance(x, str): x = conf.raw_layer(load=x) if not isinstance(x, Gen): x = SetGen(x) if verbose is None: verbose = conf.verb n = 0 if count is not None: loop = -count elif not loop: loop = -1 if return_packets: sent_packets = PacketList() try: while loop: dt0 = None for p in x: if realtime: ct = time.time() if dt0: st = dt0 + float(p.time) - ct if st > 0: time.sleep(st) else: dt0 = ct - float(p.time) s.send(p) if return_packets: sent_packets.append(p) n += 1 if verbose: os.write(1, b".") time.sleep(inter) if loop < 0: loop += 1 except KeyboardInterrupt: pass if verbose: print("\nSent %i packets." % n) if return_packets: return sent_packets
class Ecu(object): """An Ecu object can be used to * track the states of an Ecu. * to log all modification to an Ecu. * to extract supported responses of a real Ecu. Example: >>> print("This ecu logs, tracks and creates supported responses") >>> my_virtual_ecu = Ecu() >>> my_virtual_ecu.update(PacketList([...])) >>> my_virtual_ecu.supported_responses >>> print("Another ecu just tracks") >>> my_tracking_ecu = Ecu(logging=False, store_supported_responses=False) >>> my_tracking_ecu.update(PacketList([...])) >>> print("Another ecu just logs all modifications to it") >>> my_logging_ecu = Ecu(verbose=False, store_supported_responses=False) >>> my_logging_ecu.update(PacketList([...])) >>> my_logging_ecu.log >>> print("Another ecu just creates supported responses") >>> my_response_ecu = Ecu(verbose=False, logging=False) >>> my_response_ecu.update(PacketList([...])) >>> my_response_ecu.supported_responses Parameters to initialize an Ecu object :param logging: Turn logging on or off. Default is on. :param verbose: Turn tracking on or off. Default is on. :param store_supported_responses: Create a list of supported responses if True. :param lookahead: Configuration for lookahead when computing supported responses """ # noqa: E501 def __init__(self, logging=True, verbose=True, store_supported_responses=True, lookahead=10): # type: (bool, bool, bool, int) -> None self.state = EcuState() self.verbose = verbose self.logging = logging self.store_supported_responses = store_supported_responses self.lookahead = lookahead self.log = defaultdict(list) # type: Dict[str, List[Any]] self.__supported_responses = list() # type: List[EcuResponse] self.__unanswered_packets = PacketList() def reset(self): # type: () -> None """ Resets the internal state to a default EcuState. """ self.state = EcuState(session=1) def update(self, p): # type: (Union[Packet, PacketList]) -> None """ Processes a Packet or a list of Packets, according to the chosen configuration. :param p: Packet or list of Packets """ if isinstance(p, PacketList): for pkt in p: self.update(pkt) elif not isinstance(p, Packet): raise TypeError("Provide a Packet object for an update") else: self.__update(p) def __update(self, pkt): # type: (Packet) -> None """ Processes a Packet according to the chosen configuration. :param pkt: Packet to be processed """ if self.verbose: print(repr(self), repr(pkt)) if self.logging: self.__update_log(pkt) self.__update_supported_responses(pkt) def __update_log(self, pkt): # type: (Packet) -> None """ Checks if a packet or a layer of this packet supports the function `get_log`. If `get_log` is supported, this function will be executed and the returned log information is stored in the intern log of this Ecu object. :param pkt: A Packet to be processed for log information. """ for layer in pkt.layers(): if not hasattr(layer, "get_log"): continue try: log_key, log_value = layer.get_log(pkt) except TypeError: log_key, log_value = layer.get_log.im_func(pkt) self.log[log_key].append((pkt.time, log_value)) def __update_supported_responses(self, pkt): # type: (Packet) -> None """ Stores a given packet as supported response, if a matching request packet is found in a list of the latest unanswered packets. For performance improvements, this list of unanswered packets only contains a fixed number of packets, defined by the `lookahead` parameter of this Ecu. :param pkt: Packet to be processed. """ self.__unanswered_packets.append(pkt) reduced_plist = self.__unanswered_packets[-self.lookahead:] answered, unanswered = reduced_plist.sr(lookahead=self.lookahead) self.__unanswered_packets = unanswered for req, resp in answered: added = False current_state = copy.copy(self.state) EcuState.get_modified_ecu_state(resp, req, self.state, True) if not self.store_supported_responses: continue for sup_resp in self.__supported_responses: if resp == sup_resp.key_response: if sup_resp.states is not None and \ self.state not in sup_resp.states: sup_resp.states.append(current_state) added = True break if added: continue ecu_resp = EcuResponse(current_state, responses=resp) if self.verbose: print("[+] ", repr(ecu_resp)) self.__supported_responses.append(ecu_resp) @staticmethod def sort_key_func(resp): # type: (EcuResponse) -> Tuple[bool, int, int, int] """ This sorts responses in the following order: 1. Positive responses first 2. Lower ServiceIDs first 3. Less supported states first 4. Longer (more specific) responses first :param resp: EcuResponse to be sorted :return: Tuple as sort key """ first_layer = cast(Packet, resp.key_response[0]) # type: ignore service = orb(bytes(first_layer)[0]) return (service == 0x7f, service, 0xffffffff - len(resp.states or []), 0xffffffff - len(resp.key_response)) @property def supported_responses(self): # type: () -> List[EcuResponse] """ Returns a sorted list of supported responses. The sort is done in a way to provide the best possible results, if this list of supported responses is used to simulate an real world Ecu with the EcuAnsweringMachine object. :return: A sorted list of EcuResponse objects """ self.__supported_responses.sort(key=self.sort_key_func) return self.__supported_responses @property def unanswered_packets(self): # type: () -> PacketList """ A list of all unanswered packets, which were processed by this Ecu object. :return: PacketList of unanswered packets """ return self.__unanswered_packets def __repr__(self): # type: () -> str return repr(self.state) @staticmethod def extend_pkt_with_logging(cls): # type: (Type[Packet]) -> Callable[[Callable[[Packet], Tuple[str, Any]]], None] # noqa: E501 """ Decorator to add a function as 'get_log' method to a given class. This allows dynamic modifications and additions to a protocol. :param cls: A packet class to be modified :return: Decorator function """ def decorator_function(f): # type: (Callable[[Packet], Tuple[str, Any]]) -> None setattr(cls, "get_log", f) return decorator_function
class Automaton: states = {} # type: Dict[str, _StateWrapper] state = None # type: ATMT.NewStateRequested recv_conditions = {} # type: Dict[str, List[_StateWrapper]] conditions = {} # type: Dict[str, List[_StateWrapper]] ioevents = {} # type: Dict[str, List[_StateWrapper]] timeout = { } # type: Dict[str, List[Tuple[int, _StateWrapper]]] # noqa: E501 actions = {} # type: Dict[str, List[_StateWrapper]] initial_states = [] # type: List[_StateWrapper] stop_states = [] # type: List[_StateWrapper] ionames = [] # type: List[str] iosupersockets = [] # type: List[SuperSocket] # Internals def __init__(self, *args, **kargs): # type: (Any, Any) -> None external_fd = kargs.pop("external_fd", {}) self.send_sock_class = kargs.pop("ll", conf.L3socket) self.recv_sock_class = kargs.pop("recvsock", conf.L2listen) self.is_atmt_socket = kargs.pop("is_atmt_socket", False) self.started = threading.Lock() self.threadid = None # type: Optional[int] self.breakpointed = None self.breakpoints = set() # type: Set[_StateWrapper] self.interception_points = set() # type: Set[_StateWrapper] self.intercepted_packet = None # type: Union[None, Packet] self.debug_level = 0 self.init_args = args self.init_kargs = kargs self.io = type.__new__(type, "IOnamespace", (), {}) self.oi = type.__new__(type, "IOnamespace", (), {}) self.cmdin = ObjectPipe[Message]("cmdin") self.cmdout = ObjectPipe[Message]("cmdout") self.ioin = {} self.ioout = {} self.packets = PacketList() # type: PacketList for n in self.__class__.ionames: extfd = external_fd.get(n) if not isinstance(extfd, tuple): extfd = (extfd, extfd) ioin, ioout = extfd if ioin is None: ioin = ObjectPipe("ioin") else: ioin = self._IO_fdwrapper(ioin, None) if ioout is None: ioout = ObjectPipe("ioout") else: ioout = self._IO_fdwrapper(None, ioout) self.ioin[n] = ioin self.ioout[n] = ioout ioin.ioname = n ioout.ioname = n setattr(self.io, n, self._IO_mixer(ioout, ioin)) setattr(self.oi, n, self._IO_mixer(ioin, ioout)) for stname in self.states: setattr(self, stname, _instance_state(getattr(self, stname))) self.start() def parse_args(self, debug=0, store=1, **kargs): # type: (int, int, Any) -> None self.debug_level = debug if debug: conf.logLevel = logging.DEBUG self.socket_kargs = kargs self.store_packets = store def master_filter(self, pkt): # type: (Packet) -> bool return True def my_send(self, pkt): # type: (Packet) -> None self.send_sock.send(pkt) # Utility classes and exceptions class _IO_fdwrapper: def __init__( self, rd, # type: Union[int, ObjectPipe[bytes], None] wr # type: Union[int, ObjectPipe[bytes], None] ): # type: (...) -> None if rd is not None and not isinstance(rd, (int, ObjectPipe)): rd = rd.fileno() # type: ignore if wr is not None and not isinstance(wr, (int, ObjectPipe)): wr = wr.fileno() # type: ignore self.rd = rd self.wr = wr def fileno(self): # type: () -> int if isinstance(self.rd, ObjectPipe): return self.rd.fileno() elif isinstance(self.rd, int): return self.rd return 0 def read(self, n=65535): # type: (int) -> Optional[bytes] if isinstance(self.rd, ObjectPipe): return self.rd.recv(n) elif isinstance(self.rd, int): return os.read(self.rd, n) return None def write(self, msg): # type: (bytes) -> int if isinstance(self.wr, ObjectPipe): return self.wr.send(msg) elif isinstance(self.wr, int): return os.write(self.wr, msg) return 0 def recv(self, n=65535): # type: (int) -> Optional[bytes] return self.read(n) def send(self, msg): # type: (bytes) -> int return self.write(msg) class _IO_mixer: def __init__( self, rd, # type: ObjectPipe[Any] wr, # type: ObjectPipe[Any] ): # type: (...) -> None self.rd = rd self.wr = wr def fileno(self): # type: () -> Any if isinstance(self.rd, ObjectPipe): return self.rd.fileno() return self.rd def recv(self, n=None): # type: (Optional[int]) -> Any return self.rd.recv(n) def read(self, n=None): # type: (Optional[int]) -> Any return self.recv(n) def send(self, msg): # type: (str) -> int return self.wr.send(msg) def write(self, msg): # type: (str) -> int return self.send(msg) class AutomatonException(Exception): def __init__(self, msg, state=None, result=None): # type: (str, Optional[Message], Optional[str]) -> None Exception.__init__(self, msg) self.state = state self.result = result class AutomatonError(AutomatonException): pass class ErrorState(AutomatonException): pass class Stuck(AutomatonException): pass class AutomatonStopped(AutomatonException): pass class Breakpoint(AutomatonStopped): pass class Singlestep(AutomatonStopped): pass class InterceptionPoint(AutomatonStopped): def __init__(self, msg, state=None, result=None, packet=None): # type: (str, Optional[Message], Optional[str], Optional[str]) -> None # noqa: E501 Automaton.AutomatonStopped.__init__(self, msg, state=state, result=result) # noqa: E501 self.packet = packet class CommandMessage(AutomatonException): pass # Services def debug(self, lvl, msg): # type: (int, str) -> None if self.debug_level >= lvl: log_runtime.debug(msg) def send(self, pkt): # type: (Packet) -> None if self.state.state in self.interception_points: self.debug(3, "INTERCEPT: packet intercepted: %s" % pkt.summary()) self.intercepted_packet = pkt self.cmdout.send( Message(type=_ATMT_Command.INTERCEPT, state=self.state, pkt=pkt)) cmd = self.cmdin.recv() if not cmd: self.debug(3, "CANCELLED") return self.intercepted_packet = None if cmd.type == _ATMT_Command.REJECT: self.debug(3, "INTERCEPT: packet rejected") return elif cmd.type == _ATMT_Command.REPLACE: pkt = cmd.pkt self.debug(3, "INTERCEPT: packet replaced by: %s" % pkt.summary()) # noqa: E501 elif cmd.type == _ATMT_Command.ACCEPT: self.debug(3, "INTERCEPT: packet accepted") else: raise self.AutomatonError("INTERCEPT: unknown verdict: %r" % cmd.type) # noqa: E501 self.my_send(pkt) self.debug(3, "SENT : %s" % pkt.summary()) if self.store_packets: self.packets.append(pkt.copy()) def __iter__(self): # type: () -> Automaton return self def __del__(self): # type: () -> None self.stop() def _run_condition(self, cond, *args, **kargs): # type: (_StateWrapper, Any, Any) -> None try: self.debug(5, "Trying %s [%s]" % (cond.atmt_type, cond.atmt_condname)) # noqa: E501 cond(self, *args, **kargs) except ATMT.NewStateRequested as state_req: self.debug(2, "%s [%s] taken to state [%s]" % (cond.atmt_type, cond.atmt_condname, state_req.state)) # noqa: E501 if cond.atmt_type == ATMT.RECV: if self.store_packets: self.packets.append(args[0]) for action in self.actions[cond.atmt_condname]: self.debug(2, " + Running action [%s]" % action.__name__) action(self, *state_req.action_args, **state_req.action_kargs) raise except Exception as e: self.debug(2, "%s [%s] raised exception [%s]" % (cond.atmt_type, cond.atmt_condname, e)) # noqa: E501 raise else: self.debug(2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname)) # noqa: E501 def _do_start(self, *args, **kargs): # type: (Any, Any) -> None ready = threading.Event() _t = threading.Thread(target=self._do_control, args=(ready, ) + (args), kwargs=kargs, name="scapy.automaton _do_start") _t.daemon = True _t.start() ready.wait() def _do_control(self, ready, *args, **kargs): # type: (threading.Event, Any, Any) -> None with self.started: self.threadid = threading.current_thread().ident if self.threadid is None: self.threadid = 0 # Update default parameters a = args + self.init_args[len(args):] k = self.init_kargs.copy() k.update(kargs) self.parse_args(*a, **k) # Start the automaton self.state = self.initial_states[0](self) self.send_sock = self.send_sock_class(**self.socket_kargs) self.listen_sock = self.recv_sock_class(**self.socket_kargs) self.packets = PacketList(name="session[%s]" % self.__class__.__name__) # noqa: E501 singlestep = True iterator = self._do_iter() self.debug(3, "Starting control thread [tid=%i]" % self.threadid) # Sync threads ready.set() try: while True: c = self.cmdin.recv() if c is None: return None self.debug(5, "Received command %s" % c.type) if c.type == _ATMT_Command.RUN: singlestep = False elif c.type == _ATMT_Command.NEXT: singlestep = True elif c.type == _ATMT_Command.FREEZE: continue elif c.type == _ATMT_Command.STOP: if self.stop_states: # There is a stop state self.state = self.stop_states[0](self) iterator = self._do_iter() else: # Act as FORCESTOP break elif c.type == _ATMT_Command.FORCESTOP: break while True: state = next(iterator) if isinstance(state, self.CommandMessage): break elif isinstance(state, self.Breakpoint): c = Message(type=_ATMT_Command.BREAKPOINT, state=state) # noqa: E501 self.cmdout.send(c) break if singlestep: c = Message(type=_ATMT_Command.SINGLESTEP, state=state) # noqa: E501 self.cmdout.send(c) break except (StopIteration, RuntimeError): c = Message(type=_ATMT_Command.END, result=self.final_state_output) self.cmdout.send(c) except Exception as e: exc_info = sys.exc_info() self.debug( 3, "Transferring exception from tid=%i:\n%s" % (self.threadid, traceback.format_exception(*exc_info))) # noqa: E501 m = Message(type=_ATMT_Command.EXCEPTION, exception=e, exc_info=exc_info) # noqa: E501 self.cmdout.send(m) self.debug(3, "Stopping control thread (tid=%i)" % self.threadid) self.threadid = None def _do_iter(self): # type: () -> Iterator[Union[Automaton.AutomatonException, Automaton.AutomatonStopped, ATMT.NewStateRequested, None]] # noqa: E501 while True: try: self.debug(1, "## state=[%s]" % self.state.state) # Entering a new state. First, call new state function if self.state.state in self.breakpoints and self.state.state != self.breakpointed: # noqa: E501 self.breakpointed = self.state.state yield self.Breakpoint( "breakpoint triggered on state %s" % self.state.state, # noqa: E501 state=self.state.state) self.breakpointed = None state_output = self.state.run() if self.state.error: raise self.ErrorState( "Reached %s: [%r]" % (self.state.state, state_output), # noqa: E501 result=state_output, state=self.state.state) # noqa: E501 if self.state.final: self.final_state_output = state_output return if state_output is None: state_output = () elif not isinstance(state_output, list): state_output = state_output, # If there are commandMessage, we should skip immediate # conditions. if not select_objects([self.cmdin], 0): # Then check immediate conditions for cond in self.conditions[self.state.state]: self._run_condition(cond, *state_output) # If still there and no conditions left, we are stuck! if (len(self.recv_conditions[self.state.state]) == 0 and len(self.ioevents[self.state.state]) == 0 and len(self.timeout[self.state.state]) == 1): raise self.Stuck("stuck in [%s]" % self.state.state, state=self.state.state, result=state_output) # Finally listen and pay attention to timeouts expirations = iter(self.timeout[self.state.state]) next_timeout, timeout_func = next(expirations) t0 = time.time() fds = [self.cmdin] if len(self.recv_conditions[self.state.state]) > 0: fds.append(self.listen_sock) for ioev in self.ioevents[self.state.state]: fds.append(self.ioin[ioev.atmt_ioname]) while True: t = time.time() - t0 if next_timeout is not None: if next_timeout <= t: self._run_condition(timeout_func, *state_output) next_timeout, timeout_func = next(expirations) if next_timeout is None: remain = 0 else: remain = next_timeout - t self.debug(5, "Select on %r" % fds) r = select_objects(fds, remain) self.debug(5, "Selected %r" % r) for fd in r: self.debug(5, "Looking at %r" % fd) if fd == self.cmdin: yield self.CommandMessage( "Received command message") # noqa: E501 elif fd == self.listen_sock: pkt = self.listen_sock.recv(MTU) if pkt is not None: if self.master_filter(pkt): self.debug(3, "RECVD: %s" % pkt.summary()) # noqa: E501 for rcvcond in self.recv_conditions[ self.state.state]: # noqa: E501 self._run_condition( rcvcond, pkt, *state_output) # noqa: E501 else: self.debug(4, "FILTR: %s" % pkt.summary()) # noqa: E501 else: self.debug(3, "IOEVENT on %s" % fd.ioname) for ioevt in self.ioevents[self.state.state]: if ioevt.atmt_ioname == fd.ioname: self._run_condition( ioevt, fd, *state_output) # noqa: E501 except ATMT.NewStateRequested as state_req: self.debug(2, "switching from [%s] to [%s]" % (self.state.state, state_req.state)) # noqa: E501 self.state = state_req yield state_req def __repr__(self): # type: () -> str return "<Automaton %s [%s]>" % (self.__class__.__name__, [ "HALTED", "RUNNING" ][self.started.locked()]) # Public API def add_interception_points(self, *ipts): # type: (Any) -> None for ipt in ipts: if hasattr(ipt, "atmt_state"): ipt = ipt.atmt_state self.interception_points.add(ipt) def remove_interception_points(self, *ipts): # type: (Any) -> None for ipt in ipts: if hasattr(ipt, "atmt_state"): ipt = ipt.atmt_state self.interception_points.discard(ipt) def add_breakpoints(self, *bps): # type: (Any) -> None for bp in bps: if hasattr(bp, "atmt_state"): bp = bp.atmt_state self.breakpoints.add(bp) def remove_breakpoints(self, *bps): # type: (Any) -> None for bp in bps: if hasattr(bp, "atmt_state"): bp = bp.atmt_state self.breakpoints.discard(bp) def start(self, *args, **kargs): # type: (Any, Any) -> None if not self.started.locked(): self._do_start(*args, **kargs) def run( self, resume=None, # type: Optional[Message] wait=True # type: Optional[bool] ): # type: (...) -> Any if resume is None: resume = Message(type=_ATMT_Command.RUN) self.cmdin.send(resume) if wait: try: c = self.cmdout.recv() if c is None: return None except KeyboardInterrupt: self.cmdin.send(Message(type=_ATMT_Command.FREEZE)) return None if c.type == _ATMT_Command.END: return c.result elif c.type == _ATMT_Command.INTERCEPT: raise self.InterceptionPoint("packet intercepted", state=c.state.state, packet=c.pkt) # noqa: E501 elif c.type == _ATMT_Command.SINGLESTEP: raise self.Singlestep("singlestep state=[%s]" % c.state.state, state=c.state.state) # noqa: E501 elif c.type == _ATMT_Command.BREAKPOINT: raise self.Breakpoint("breakpoint triggered on state [%s]" % c.state.state, state=c.state.state) # noqa: E501 elif c.type == _ATMT_Command.EXCEPTION: six.reraise(c.exc_info[0], c.exc_info[1], c.exc_info[2]) return None def runbg(self, resume=None, wait=False): # type: (Optional[Message], Optional[bool]) -> None self.run(resume, wait) def next(self): # type: () -> Any return self.run(resume=Message(type=_ATMT_Command.NEXT)) __next__ = next def _flush_inout(self): # type: () -> None with self.started: # Flush command pipes while True: r = select_objects([self.cmdin, self.cmdout], 0) if not r: break for fd in r: fd.recv() def stop(self): # type: () -> None self.cmdin.send(Message(type=_ATMT_Command.STOP)) self._flush_inout() def forcestop(self): # type: () -> None self.cmdin.send(Message(type=_ATMT_Command.FORCESTOP)) self._flush_inout() def restart(self, *args, **kargs): # type: (Any, Any) -> None self.stop() self.start(*args, **kargs) def accept_packet( self, pkt=None, # type: Optional[Packet] wait=False # type: Optional[bool] ): # type: (...) -> Any rsm = Message() if pkt is None: rsm.type = _ATMT_Command.ACCEPT else: rsm.type = _ATMT_Command.REPLACE rsm.pkt = pkt return self.run(resume=rsm, wait=wait) def reject_packet( self, wait=False # type: Optional[bool] ): # type: (...) -> Any rsm = Message(type=_ATMT_Command.REJECT) return self.run(resume=rsm, wait=wait)
def __gen_send_mod(s, x, inter=0, loop=0, count=None, verbose=None, realtime=None, return_packets=False, port_random_flag=False, size_random_flag=False, src_random_flag=False, specific_subnet_random=False, source_addr='Default', pcktcount=None, log=None, *args, **kargs): # noqa: E501 totaltimeelapsedns = 0.0 totaltimeelapseds = 0.0 if isinstance(x, str): x = conf.raw_layer(load=x) if not isinstance(x, Gen): x = SetGen(x) if verbose is None: verbose = conf.verb n = 0 if count is not None: loop = -count elif not loop: loop = -1 if return_packets: sent_packets = PacketList() try: startVelkoSec = time.time() while loop: dt0 = None for p in x: if realtime: ct = time.time() if dt0: st = dt0 + p.time - ct if st > 0: time.sleep(st) else: dt0 = ct - p.time if (p.proto == 1): p.type = int(random.randrange(0, 255)) p.code = int(random.randrange(0, 255)) if (port_random_flag): targ_port = int(random.randrange(0, 65535)) p.dport = targ_port if (size_random_flag): packet_size = int( random.randrange(0, 6550) ) # 7 I removed 7 because there seems to be some boundary crossing(bleeding) p.add_payload((str(_generatePacket(packet_size))).encode()) if (src_random_flag): p.src = socket.inet_ntoa( struct.pack('>I', random.randint(1, 0xffffffff))) elif (specific_subnet_random): try: subnet = IPv4Network(source_addr) bits = random.getrandbits(subnet.max_prefixlen - subnet.prefixlen) p.src = str(IPv4Address(subnet.network_address + bits)) except ValueError: print("Something is wrong!sendrcv ") if ((n % int(pcktcount)) == 0): endVelkoSec = time.time() totaltimeelapseds += (endVelkoSec - startVelkoSec) print("\n+++TIMESTAMP+++\nTimestamp taken after:", n, "packets") #print('{:%Y-%m-%d_%H:%M:%S}'.format(datetime.datetime.now())+"\n") print((datetime.datetime.now() ).strftime('%Y-%m-%d %H:%M:%S.%f')[:-2] + " (UTC)\n") print("TIME(s): ", (endVelkoSec - startVelkoSec)) print("TIME(ns): ", (endVelkoSec - startVelkoSec) * 1000000000) print("TOTAL TIME(s): ", totaltimeelapseds) print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++\n" ) #LOG SECTION # file_name=log # f = open(file_name, 'a+') # f.write("\n+++TIMESTAMP+++\nTimestamp taken after: "+str(n)+"\n") # f.write(datetime.datetime.utcnow().strftime('%Y-%m-%d %H-%M-%S_%f')[:-2]+" (UTC)\n") # f.write("TIME(ns): "+str((endVelkoSec - startVelkoSec)*1000000000)+"\n") # f.write("TIME(s): "+ str(endVelkoSec-startVelkoSec)+"\n") # f.write("TOTAL TIME ELAPSED(s): "+str(totaltimeelapseds)+"\n") # f.write("\n===WholePacket===\n") # tmp=p.show(dump=True) # f.write(str(tmp)) # f.close() # TODO: Should log only if log is activated #log_packet(p,log) #END LOG SECTION s.send(p) if (p.proto == 1): print( datetime.datetime.utcnow().strftime( '%Y-%m-%d_%H-%M-%S_%f')[:-2] + "(UTC)\t", "proto", p.proto, "\tsrc", p.src, "\tdst", p.dst, "\tcode", p.code, "\ttype", p.type, "\tLength(b)", len(p)) else: print( datetime.datetime.utcnow().strftime( '%Y-%m-%d_%H-%M-%S_%f')[:-2] + "(UTC)\t", "proto", p.proto, "\tsrc", p.src, "\tsport", p.sport, "\tdst", p.dst, "\tdport", p.dport, "\tLength(b)", len(p)) # time.sleep(5) if return_packets: sent_packets.append(p) n += 1 if verbose: os.write(1, b".") time.sleep(inter) if loop < 0: loop += 1 except KeyboardInterrupt: pass if verbose: print("\nSent %i packets." % n) if return_packets: return sent_packets
def defrag(plist): """defrag(plist) -> ([not fragmented], [defragmented], [ [bad fragments], [bad fragments], ... ])""" frags = {} nofrag = PacketList() for p in plist: ip = p[IP] if IP not in p: nofrag.append(p) continue if ip.frag == 0 and ip.flags & 1 == 0: nofrag.append(p) continue uniq = (ip.id,ip.src,ip.dst,ip.proto) if uniq in frags: frags[uniq].append(p) else: frags[uniq] = PacketList([p]) defrag = [] missfrag = [] for lst in frags.itervalues(): lst.sort(lambda x,y:cmp(x.frag, y.frag)) p = lst[0] if p.frag > 0: missfrag.append(lst) continue p = p.copy() if Padding in p: del(p[Padding].underlayer.payload) ip = p[IP] if ip.len is None or ip.ihl is None: clen = len(ip.payload) else: clen = ip.len - (ip.ihl<<2) txt = Raw() for q in lst[1:]: if clen != q.frag<<3: if clen > q.frag<<3: warning("Fragment overlap (%i > %i) %r || %r || %r" % (clen, q.frag<<3, p,txt,q)) missfrag.append(lst) txt = None break if q[IP].len is None or q[IP].ihl is None: clen += len(q[IP].payload) else: clen += q[IP].len - (q[IP].ihl<<2) if Padding in q: del(q[Padding].underlayer.payload) txt.add_payload(q[IP].payload.copy()) if txt is None: continue ip.flags &= ~1 # !MF del(ip.chksum) del(ip.len) p = p/txt defrag.append(p) defrag2=PacketList() for p in defrag: defrag2.append(p.__class__(str(p))) return nofrag,defrag2,missfrag