Search code examples
pythonparsingrhel6

Parse filename from Dumpcap output


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


Solution

  • 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()