我已经实现了一个脚本来解析ERF文件以从数据包中获取DNS记录。该脚本在Linux下运行,但不能在Windows下运行。
我试图简化它并从文件中只读取两个数据包,结果完全错误。
以下是前两个数据包的输出:
rlen 1232
wlen 1213
ts: (5822080496043415499L,)
rec len: 1232
protocol: 6 rem 1180
tcp
src port: 59626
remaining length based on the erf header 1160 remaining length based in IP total length 1155
----------------------
rlen 44076
wlen 13638
ts: (246640611164160L,)
rec len: 44076
protocol: 9 rem 44024
----------------------
对于第一个数据包,输出是正确的,但对于第二个数据包,一切都是错误的。我所做的是从ERF头读取记录长度以跟踪数据包边界。当我打印tcp的有效负载时,我发现下一个数据包的erf头是在tcp的有效负载中。当我在linux下运行代码时,这个问题并没有发生。
谁能告诉我我做错了什么?
这是我的代码:
if __name__ == '__main__':
argv= sys.argv
outputFile=''
inputFile=''
dnsPacketCounter=0
ethH = {}
ipHeader = {}
ipH = {}
totalPackets=0
if len(argv) ==1:
print 'erfParser.py -i <inputfile> -o <outputfile>'
sys.exit(0)
elif len(argv) == 2:
if argv[1] == '-h':
print 'erfParser.py -i <inputfile> -o <outputfile>'
sys.exit(0)
elif len(argv) == 5:
if argv[1] == '-i':
inputFile = argv[2].strip()
elif argv[3] == '-i':
inputFile = argv[4].strip()
if argv[1] == '-o':
outputFile = argv[2].strip()
elif argv[3] == '-o':
outputFile= argv[4].strip()
else:
# Open the trace file
print 'erfParser.py -i <inputfile> -o <outputfile>'
sys.exit(0)
try:
packets = open(inputFile , 'r+')
except IOError:
print 'The file: ',inputFile,' not found.'
sys.exit(0)
try:
outFile=open(outputFile+'.txt', 'w+')
except IOError:
print 'The file: ',outputFile,' can not be opened.'
sys.exit(0)
ts=packets.read(8)
i=0
while ts:
erf={}
hdr = packets.read(8)
#print ts.encode('hex')
totalPackets=totalPackets+1
erf= getERFHeader(ts,hdr)
print 'rlen',erf['rlen']
print 'wlen',erf['wlen']
print 'ts: ',erf['ts']
remainingLength=erf['rlen']- 16
print 'rec len: ',erf['rlen']
if erf['type'] == 0x07:
ext=packets.read(8)
remainingLength=remainingLength- 8
pad=packets.read(2) # pad
remainingLength=remainingLength- 2
ethH= packets.read(14) # ethernet header `16 bytes
remainingLength=remainingLength- 14
ipHeader= packets.read(20) #ip header length is 20 bytes
remainingLength=remainingLength- 20
ipH= getIPHeader(ipHeader)
print 'protocol: ',ipH['protocol'],' rem ',remainingLength
if ipH['protocol'] ==TCP:
print 'tcp'
hdr = packets.read(20)
remainingLength=remainingLength- 20
tcpHeader=getTCPHeader(hdr)
tcpPayload= packets.read(remainingLength)
print 'src port: ',tcpHeader['srcPort']
# print 'tcp payload in hex: ',tcpPayload.encode('hex')
print 'remaining length based on the erf header',remainingLength,'remaining length based in IP total length' ,ipH['totalL']-40
print '----------------------'
ts=packets.read(8)
i=i+1
if i==2:
break;
pass
答案 0 :(得分:1)
谁能告诉我我做错了什么?
是的,我可以告诉你,你是以文本模式而不是二进制模式打开文件:
packets = open(inputFile , 'r+')
引用the Python documentation for open()
:
UN * Xes,例如Linux是&#34;系统没有这种区别&#34;,因为Python模式
'r+'
,'w+'
和'a+'
打开文件进行更新(读写);请注意'w+'
截断文件。将'b'
附加到模式以在二进制模式下打开文件,在区分二进制文件和文本文件的系统上;在没有这种区别的系统上,添加'b'
无效。
open()
是以&#34;的UN * X版本为模型的。标准I / O库&#34;,其中行以\n
结尾。在Windows上,行以\r\n
结尾,并在&#34;标准I / O库中打开&#34;可以:
\r\n
在读取时会以\n
和\n
的形式显示给程序line,写成\r\n
,因此为UN * X编写的程序可以在Windows上运行,而不必担心行尾序列; 因此,它是一个“区分”二进制文件和文本文件的系统,至少在某些I / O库中是这样。 (在I / O的最低级别,即CreateFile()
,ReadFile()
和WriteFile()
调用,Windows没有这样的区别 - 它将文件视为原始字节序列,没有& #34;以文本&#34;选项打开,正如UN * X系统对open()
,read()
和write()
所做的那样 - 但是在I / O的所有级别上都是有意的UN * X兼容,它们提供文本与二进制选项。)
ERF文件是二进制文件,因此您需要使用'rb+'
或'r+b'
而不是'r+'
打开。这对UN * Xes(如Linux)没有任何影响,但会在Windows上为您提供原始二进制数据。
(实际上,只需'rb'
即可 - 如果您不打算写信给您正在阅读的文件,则+
不是必需的,并创建意外覆盖文件的风险。)