博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

python调用tcpdump抓包过滤

Posted on 2017-09-12 16:04  红与黑hyh  阅读(1337)  评论(0编辑  收藏  举报

之前在linux用python脚本写一个抓包分析小工具,实在不想用什么libpcap、pypcap所以,简单来了个tcpdump加grep搞定。基本思路是分别起tcpdump和grep两个进程,进程直接通过pipe交换数据,简单代码如下:

 

#! /usr/bin/python  
  
def tcpdump():  
    import subprocess, fcntl, os  
    # sudo tcpdump -i eth0 -n -s 0 -w - | grep -a -o -E "Host: .*|GET /.*"  
    cmd1 = ['tcpdump', '-i', 'eth0', '-n','-B', '4096','-s', '0', '-w', '-']  
    cmd2 = ['grep', '--line-buffered', '-a', '-o', '-E', 'Host: .*|GET /.*']  
    p1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE)  
    p2 = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stdin=p1.stdout)  
      
    flags = fcntl.fcntl(p2.stdout.fileno(), fcntl.F_GETFL)  
    fcntl.fcntl(p2.stdout.fileno(), fcntl.F_SETFL, (flags | os.O_NDELAY | os.O_NONBLOCK))  
    return p2  
  
  
def poll_tcpdump(proc):  
    #print 'poll_tcpdump....'  
    import select  
    txt = None  
    while True:  
        # wait 1/10 second   
        readReady, _, _ = select.select([proc.stdout.fileno()], [], [], 0.1)  
        if not len(readReady):  
            break  
        try:  
            for line in iter(proc.stdout.readline, ""):  
                if txt is None:  
                    txt = ''  
                txt += line  
        except IOError:  
            print 'data empty...'  
            pass  
        break  
    return txt  
  
  
proc = tcpdump()  
while True:  
    text = poll_tcpdump(proc)  
    if text:  
        print '>>>> ' + text  

  运行效果:

其中值得注意tcpdump中'-B', '4096'这个参数,官方文档貌似没有明确提及,但是它是你解决丢包的关键地方之一,当然还有-s这个参数也得好好利用!其他的大家可以自由发挥!