1. 程式人生 > >python呼叫tcpdump抓包過濾

python呼叫tcpdump抓包過濾

之前在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這個引數也得好好利用!其他的大家可以自由發揮!