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)))
Esempio n. 2
0
 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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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
Esempio n. 6
0
 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)
Esempio n. 7
0
 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)