def __init__(self, logger, start_ts): self.logger = logger self.fifo = None self.start_ts = start_ts # generate a temp fifo pipe self.fifo_name = tempfile.mktemp() self.wireshark_pid = None try: self.logger.pre_cmd('Starting pipe capture monitor') os.mkfifo(self.fifo_name) self.logger.post_cmd(RC_OK()) # try to locate wireshark on the machine self.wireshark_exe = self.locate_wireshark() # we found wireshark - try to launch a process if self.wireshark_exe: self.wireshark_pid = self.launch_wireshark() # did we succeed ? if not self.wireshark_pid: self.logger.info( format_text( "*** Please manually run 'wireshark -k -i {0}' ***". format(self.fifo_name), 'bold')) # blocks until pipe is connected self.logger.pre_cmd("Waiting for Wireshark pipe connection") self.fifo = os.open(self.fifo_name, os.O_WRONLY) self.logger.post_cmd(RC_OK()) self.logger.info( format_text('\n*** Capture monitoring started ***\n', 'bold')) # open for write using a PCAP writer self.writer = RawPcapWriter(self.fifo_name, linktype=1, sync=True) self.writer._write_header(None) # register a poller self.poll = select.poll() self.poll.register(self.fifo, select.EPOLLERR) self.is_init = True except KeyboardInterrupt as e: self.deinit() self.logger.post_cmd(RC_ERR("")) raise TRexError("*** pipe monitor aborted...cleaning up") except OSError as e: self.deinit() self.logger.post_cmd(RC_ERR("")) raise TRexError("failed to create pipe {0}\n{1}".format( self.fifo_name, str(e)))
def _write_header(self, pkt): if self.linktype == None: if type(pkt) is list or type(pkt) is tuple or isinstance(pkt, BasePacketList): pkt = pkt[0] try: self.linktype = conf.l2types[pkt.__class__] except KeyError: self.linktype = 1 RawPcapWriter._write_header(self, pkt)
def commit_packet(self, packet): """Apply the command line expressions(s) and routine file (if any) to the packet and, if output it being piped to somewhere other than the terminal, dump the packet into the outgoing pcap stream. """ self.apply_cmdline_exps(packet) self.apply_routine_file(packet) # print out changes to each packet if --verbose if FLAGS.verbose: diff_list = packet.diff(self.orig_packet) if len(diff_list) > 0: for (attr, my_val, other_val) in diff_list: sys.stderr.write(attr + ': ' + str(other_val) + ' -> ' + str(my_val) + '\n') sys.stderr.write('\n') if self.pcap is None: sys.stderr.write( 'Attempted to dump packets without first reading them -- make sure to call packet_generator()' ) sys.exit(1) else: # make a temp file, use scapy's RawPcapWriter to write the # current packet to that file, then read that same packet # in using a new instance of pcapy.open_offline, then # write out to stdout the packet that we just read back # in, then finally delete the temp file # # we have to do it this way in case the size of the packet # changed, in which case the packet's pcap header needs to # be regenerated. RawPcapWriter does this for us # # on reflection, it would be pretty straightforward to # copy RawPcapWriter's code for generating the pcap # header(s) and do it ourselves, without the messy temp # file stuff. this code should be re-worked to do that. # temp = tempfile.mkstemp() rpw = RawPcapWriter(self.temp[1], linktype=220, sync=True) #print >> sys.stderr, self.temp[1] rpw.write(packet.repack()) mypcap = pcapy.open_offline(self.temp[1]) (myhdr, mypack) = mypcap.next() if not sys.stdout.isatty(): self.out.dump(myhdr, mypack)
def commit_packet(self, packet): """Apply the command line expressions(s) and routine file (if any) to the packet and, if output it being piped to somewhere other than the terminal, dump the packet into the outgoing pcap stream. """ self.apply_cmdline_exps(packet) self.apply_routine_file(packet) # print out changes to each packet if --verbose if FLAGS.verbose: diff_list = packet.diff(self.orig_packet) if len(diff_list) > 0: for (attr, my_val, other_val) in diff_list: sys.stderr.write(attr + ': ' + str(other_val) + ' -> ' + str(my_val) + '\n') sys.stderr.write('\n') if self.pcap is None: sys.stderr.write('Attempted to dump packets without first reading them -- make sure to call packet_generator()') sys.exit(1) else: # make a temp file, use scapy's RawPcapWriter to write the # current packet to that file, then read that same packet # in using a new instance of pcapy.open_offline, then # write out to stdout the packet that we just read back # in, then finally delete the temp file # # we have to do it this way in case the size of the packet # changed, in which case the packet's pcap header needs to # be regenerated. RawPcapWriter does this for us # # on reflection, it would be pretty straightforward to # copy RawPcapWriter's code for generating the pcap # header(s) and do it ourselves, without the messy temp # file stuff. this code should be re-worked to do that. # temp = tempfile.mkstemp() rpw = RawPcapWriter(self.temp[1], linktype = 220, sync=True) #print >> sys.stderr, self.temp[1] rpw.write(packet.repack()) mypcap = pcapy.open_offline(self.temp[1]) (myhdr, mypack) = mypcap.next() if not sys.stdout.isatty(): self.out.dump(myhdr, mypack)
class CaptureMonitorWriterPipe(CaptureMonitorWriter): def __init__(self, logger, start_ts): self.logger = logger self.fifo = None self.start_ts = start_ts # generate a temp fifo pipe self.fifo_name = tempfile.mktemp() self.wireshark_pid = None try: self.logger.pre_cmd('Starting pipe capture monitor') os.mkfifo(self.fifo_name) self.logger.post_cmd(RC_OK()) # try to locate wireshark on the machine self.wireshark_exe = self.locate_wireshark() # we found wireshark - try to launch a process if self.wireshark_exe: self.wireshark_pid = self.launch_wireshark() # did we succeed ? if not self.wireshark_pid: self.logger.info( format_text( "*** Please manually run 'wireshark -k -i {0}' ***". format(self.fifo_name), 'bold')) # blocks until pipe is connected self.logger.pre_cmd("Waiting for Wireshark pipe connection") self.fifo = os.open(self.fifo_name, os.O_WRONLY) self.logger.post_cmd(RC_OK()) self.logger.info( format_text('\n*** Capture monitoring started ***\n', 'bold')) # open for write using a PCAP writer self.writer = RawPcapWriter(self.fifo_name, linktype=1, sync=True) self.writer._write_header(None) # register a poller self.poll = select.poll() self.poll.register(self.fifo, select.EPOLLERR) self.is_init = True except KeyboardInterrupt as e: self.deinit() self.logger.post_cmd(RC_ERR("")) raise TRexError("*** pipe monitor aborted...cleaning up") except OSError as e: self.deinit() self.logger.post_cmd(RC_ERR("")) raise TRexError("failed to create pipe {0}\n{1}".format( self.fifo_name, str(e))) def locate_wireshark(self): self.logger.pre_cmd('Trying to locate Wireshark') wireshark_exe = spawn.find_executable('wireshark') self.logger.post_cmd(RC_OK() if wireshark_exe else RC_ERR()) if not wireshark_exe: return None dumpcap = os.path.join(os.path.dirname(wireshark_exe), 'dumpcap') self.logger.pre_cmd("Checking permissions on '{}'".format(dumpcap)) if not os.access(dumpcap, os.X_OK): self.logger.post_cmd(RC_ERR('bad permissions on dumpcap')) return None self.logger.post_cmd(RC_OK()) return wireshark_exe # try to launch wireshark... returns true on success def launch_wireshark(self): cmd = '{0} -k -i {1}'.format(self.wireshark_exe, self.fifo_name) self.logger.pre_cmd("Launching '{0}'".format(cmd)) try: devnull = open(os.devnull, 'w') self.wireshark_pid = Popen(cmd.split(), stdout=devnull, stderr=devnull, stdin=subprocess.PIPE, preexec_fn=os.setpgrp, close_fds=True) self.logger.post_cmd(RC_OK()) return True except OSError as e: self.wireshark_pid = None self.logger.post_cmd(RC_ERR()) return False def deinit(self): try: if self.fifo: os.close(self.fifo) self.fifo = None if self.fifo_name: os.unlink(self.fifo_name) self.fifo_name = None except OSError: pass def periodic_check(self): self.check_pipe() def check_pipe(self): if self.poll.poll(0): raise TRexError('pipe has been disconnected') def handle_pkts(self, pkts): # first check the pipe is alive self.check_pipe() return self.handle_pkts_internal(pkts) def handle_pkts_internal(self, pkts): byte_count = 0 for pkt in pkts: pkt_bin = base64.b64decode(pkt['binary']) ts_sec, ts_usec = sec_split_usec(pkt['ts'] - self.start_ts) try: self.writer._write_packet(pkt_bin, sec=ts_sec, usec=ts_usec) except Exception as e: raise TRexError('fail to write packets to pipe: {}'.format( str(e))) byte_count += len(pkt_bin) return byte_count
def _write_packet(self, packet): sec = int(packet.time) usec = int(round((packet.time-sec)*1000000)) s = str(packet) caplen = len(s) RawPcapWriter._write_packet(self, s, sec, usec, caplen, caplen)
def __init__(self, filename, linktype=None, gz=False, endianness="", append=False, sync=False): RawPcapWriter.__init__(self, filename, linktype=None, gz=False, endianness="", append=False, sync=False) fdesc.setNonBlocking(self.f)