0

I am trying to parse the filename from the ouput of running dumpcap in the terminal in linux in order to automatically attach it to an email. This is the relevant functions from a larger script. proc1, stdout, and eventfile are initialized to"" and DUMPCAP is the command line string dumpcap -a duration:300 -b duration:2147483647 -c 500 -i 1 -n -p -s 2 -w test -B 20

def startdump():                       
    global DUMPCAP                     
    global dumpdirectory               
    global proc1                       
    global stdout                      
    global eventfile                   
    setDumpcapOptions()                
    print("dumpcap.exe = " + DUMPCAP)  
    os.chdir(dumpdirectory)            
    #subprocess.CREATE_NEW_CONSOLE     
    proc1 = subprocess.Popen(DUMPCAP, shell=True, stdout=subprocess.PIPE)
    for line in proc1:                 
        if 'File: ' in line:           
            parsedfile = line.split(':')
            eventfile = parsedfile[1]  
    if dc_mode == "Dumpcap Only":      
        proc1.communicate()            
        mail_man(config_file)          
     return proc1                       

def startevent():
    global EVENT
    global proc1
    global eventfile
    setEventOptions()
    print(EVENT)
    # subprocess.CREATE_NEW_CONSOLE
    proc2 = subprocess.Popen(EVENT, shell=True, stdout=subprocess.PIPE) 
    if dc_mode == "Dumpcap+Event" or dc_mode == "Trigger" or dc_mode == "Event Only":
        proc2 = proc1.communicate()
        mail_man(config_file)
    return proc2

the problem I keep having is that I can't figure out how to parse the file name from the output of dumpcap. It keeps parsing ""from the output no matter what I do. I apologize if this seems unresearched. I am a month into learning python and linux on my own and the documentation is terse and confusing online.

Should I create a function to parse the eventfile from dumpcap's output or do it right there in the script? I'm truly at a loss here. I'm not sure how dumpcap stores its output either.

The output of dumcap in the terminal is:

dumpcap.exe = dumpcap -a duration:300 -b duration:2147483647 -c 500 -i 1 -n -p -s 2 -w test -B 20
 -i 1 - f icmp and host 156.24.31.29 - c 2
/bin/sh: -i: command not found
Capturing on 'eth0'
File: test_00001_20150714141827
Packets captured: 500
Packets received/dropped on interface 'eth0': 500/0 (pcap:0/dumpcap:0/flushed:0/ps_ifdrop:0) (100.0%)
[Errno 2] No such file or directory: ''

the line File: ... contains the randomly generated name of the pcap file saved by dumpcap I am trying to parse that line from the terminal to get everything after the File: set to a variable but the conventional .split method doesn't seem to be working

The other error it gives is that Popen cannot be indexed

  • 1
    What is a typical output of your `dumpcap.exe` command? – 9000 Jul 14 '15 at 19:28
  • @9 'dumpcap.exe = dumpcap -a duration:300 -b duration:2147483647 -c 500 -i 1 -n -p -s 2 -w test -B 20 -i 1 - f icmp and host 156.24.31.29 - c 2 /bin/sh: -i: command not found Capturing on 'eth0' File: test_00001_20150714141827 Packets captured: 500 Packets received/dropped on interface 'eth0': 500/0 (pcap:0/dumpcap:0/flushed:0/ps_ifdrop:0) (100.0%) [Errno 2] No such file or directory: '' Error! Something went wrong with Mail Man. Please try again.' I apologize, I don't know how to edit that properly, but the gist is that it out puts `File: (filename)` – Googlesomething Jul 14 '15 at 19:33
  • @Googlesomething Please edit that into your question (comments don't preserve formatting). – senshin Jul 14 '15 at 19:33
  • @Googlesomething You are somehow missing closing parentheses from some of your lines - `proc1 = subprocess.Popen(DUMPCAP, s` and `parsedfile = line.split(':'`. Please double-check the code you have here and ensure that it matches the code that you're actually using. – senshin Jul 14 '15 at 19:39
  • @senshin Done. I'm now wondering if instead of parsing from the output somehow, that it would just be easier to locate the directory it saves to and attach the most recent file to the email function. Although I'm not certain how that would work with if multiple files were made from dumpcap due to maximum file size being reached and dumpcap creating a new file – Googlesomething Jul 14 '15 at 19:41

2 Answers2

0

It looks like basically you need a regexp.

import re
rx = re.compile('^File: (\S+)$', re.MULTILINE)
m = rx.search(stdout_contents)
if m:
  file_name = m.group(1)
# else: file name not detected.

Update: a minimal complete example of reading pipe's stdout; hope this helps.

import subprocess
proc = subprocess.Popen("echo foo", shell=True, stdout=subprocess.PIPE)
result = proc.communicate()
print result[0]  # must be `foo\n`
9000
  • 39,899
  • 9
  • 66
  • 104
  • what would `(stdout_contents)` be comprised of? – Googlesomething Jul 14 '15 at 20:01
  • It would be the output of dumcap in the terminal which you capture through `stdout = subprocess.PIPE`, that is, `proc2[0]`. – 9000 Jul 14 '15 at 20:15
  • This doesn't work because `'Popen object does not support indexing'`... Or thats the error I get when its run – Googlesomething Jul 14 '15 at 20:37
  • Ah, you seem to reassign `proc2` here: `proc2 = proc1.communicate()`. Please never reassign variables with values of a different type (and preferably never at all). What we need is the result of [communicate()](https://docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate). Reading the docs sort of helps, too. – 9000 Jul 14 '15 at 20:45
  • Changing the variable reassignment mistake still gave the error code of `Popen object does not support indexes` on line `m=rx.search(proc1[0])` Is there an alternative to Popen that supports indexes? The docs are harder to understand than humans – Googlesomething Jul 15 '15 at 13:14
  • Still does parse the file name from the output of `dumpcap` correctly: `AttributeError: 'NoneType' object has no attribute 'group'` referring to the line `eventfile = m.group(1)` when `out1 = proc1.communicate()` and `m=rx.search(out1[0])` – Googlesomething Jul 15 '15 at 15:35
  • Yes, you have to check that `m is not None` or `if m` or something like that, to make sure a match (hence `m`) has actually happened. – 9000 Jul 15 '15 at 15:41
  • I've done that, but it won't let me get to check whether `m` has anything stored or not due to the `Popen` indexing error – Googlesomething Jul 15 '15 at 18:02
0

Dumpcap outputs to its stderr as opposed to stdout. So I've managed to redirect the stderr to a txt file which I can then parse.

def startdump():
    global DUMPCAP, dumpdirectory, proc1
    global eventfile, dc_capfile

    DUMPCAP = ''
    print("========================[ MAIN DUMPCAP MONITORING ]===========================")
    setDumpcapOptions()
    os.chdir(dumpdirectory)
    if platform == "Linux":
        DUMPCAP = "dumpcap " + DUMPCAP
    elif platform == "Windows":
        DUMPCAP = "dumpcap.exe " + DUMPCAP
    proc1 = subprocess.Popen(DUMPCAP, shell=True, stderr=subprocess.PIPE)
    #procPID = proc1.pid
    if dc_mode == "Dumpcap Only":
        time.sleep(5)
        with open("proc1stderr.txt", 'w+') as proc1stderr:
            proc1stderr.write(str(proc1.stderr))
            for line in proc1.stderr:
                print("%s" % line)
                if "File:" in line:
                    print(line)
                    raweventfile = line.split('File: ')[1]
                    eventfile = raweventfile.strip('\[]').rstrip('\n')
                    mail_man()
            proc1.communicate()