需要帮助将源和目标端口号输出给用户,使用 Python 和 dpkt 从 pcap 文件中读取
Need help outputting the source and destination port number to the user, reading from a pcap file using Python, and dpkt
大家好,这是我第一次使用 Python 编程语言进行 PCAP 编程,这是大学的一项任务,除了一个小细节外,我几乎已经掌握了完成任务所需的一切.
我只需要获取与 IP 地址关联的源端口号和目标端口号(例如 HTTP 端口 80)的输出。
我很高兴这个答案能够指明正确的方向,帮助我自己解决问题。否则,如果它更容易回答,我想要一个关于使用了什么以及它如何解决问题的基本解释,以便我在学习和研究中进行更多 PCAP 编程时可以更好地理解它。
这是在 Unix 系统上使用 运行 FreeBSD 10.3
我已经尝试使用 dpkt.tcp、dpkt.udp、dpkt.ip 库并尝试了一些套接字库以查看是否可以实现我正在寻找的结果,但没有好运。老实说,我不确定我需要使用什么。
编辑:我确实尝试过使用 tcp.sport 和 tcp.dport,但仍然没有成功。
主要关注的地方是我添加评论的地方。
import datetime
import time
import sys
import dpkt
import socket
def printPcap(pcap):
for (ts,buf) in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf)
if eth.type == dpkt.ethernet.ETH_TYPE_IP:
ip = eth.data
ipsrc = socket.inet_ntoa(ip.src)
ipdst = socket.inet_ntoa(ip.dst)
srcport = ??? ###Stuck here for source port
dstport = ??? ###Stuck here for destination port
if ip.p == dpkt.ip.IP_PROTO_TCP:
TCP = ip.data
iptype = 'tcp'
elif ip.p == dpkt.ip.IP_PROTO_UDP:
UDP = ip.data
iptype = 'udp'
len = str(ip.len)
ttl = str(ip.ttl)
###My current output
print '[' +str(datetime.datetime.utcfromtimestamp(ts))+ '] - ' \
+ipsrc+ ':' +srcport+ ' -> ' +ipdst+ ':' +dstport+ \
' ('+iptype+', len='+len+', ttl='+ttl+')'
except:
pass
样本预期输出:
[2018-08-16 02:48:10.238506] - 172.16.11.2:61016 -> 172.16.10.2:80 (tcp, len=52, ttl=63)
也许使用ip.data
获取TCP数据包和sport
and/ordport
?
ip = eth.data
if ip.p == dpkt.ip.IP_PROTO_TCP:
tcp = ip.data
print('source port: {}, dest port: {}'.format(tcp.sport, tcp.dport))
问题是您的打印语句是伪造的,但您已使用 "bare except" 隐藏了它。正是出于这个原因,在 python 中使用 bare except 被认为是非常糟糕的做法。另请参阅此问题的答案:Should I always specify an exception type in `except` statements?
具体来说,您的 print 语句试图将一个整数连接到一个无效的字符串。
所以,修复了,并且:
if ip.p == dpkt.ip.IP_PROTO_TCP:
TCP = ip.data
iptype = 'tcp'
srcport = TCP.sport
dstport = TCP.dport
elif ip.p == dpkt.ip.IP_PROTO_UDP:
UDP = ip.data
iptype = 'udp'
srcport = UDP.sport
dstport = UDP.dport
这个打印语句有效:
print("[{}] - {}:{} -> {}:{} ({}, len={}, ttl={})".format(
datetime.datetime.utcfromtimestamp(ts), ipsrc, srcport,
ipdst, dstport, iptype, len, ttl))
最后,至少,我会将您的 except 子句更改为类似这样的内容,以便将来检测此类问题:
except Exception as exc:
print("Exception: {}".format(exc))
(请注意,我在这里使用了 python3 兼容的 print function 语法,它也适用于 python2 的 print 声明.)
编辑:
我刚刚想到另一件事。如果遇到的第一个 IP 数据包既不是 TCP 也不是 UDP,srcport
和 dstport
将不会被定义,这将导致 AttributeError
异常。留给你清理。
大家好,这是我第一次使用 Python 编程语言进行 PCAP 编程,这是大学的一项任务,除了一个小细节外,我几乎已经掌握了完成任务所需的一切.
我只需要获取与 IP 地址关联的源端口号和目标端口号(例如 HTTP 端口 80)的输出。
我很高兴这个答案能够指明正确的方向,帮助我自己解决问题。否则,如果它更容易回答,我想要一个关于使用了什么以及它如何解决问题的基本解释,以便我在学习和研究中进行更多 PCAP 编程时可以更好地理解它。
这是在 Unix 系统上使用 运行 FreeBSD 10.3
我已经尝试使用 dpkt.tcp、dpkt.udp、dpkt.ip 库并尝试了一些套接字库以查看是否可以实现我正在寻找的结果,但没有好运。老实说,我不确定我需要使用什么。
编辑:我确实尝试过使用 tcp.sport 和 tcp.dport,但仍然没有成功。
主要关注的地方是我添加评论的地方。
import datetime
import time
import sys
import dpkt
import socket
def printPcap(pcap):
for (ts,buf) in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf)
if eth.type == dpkt.ethernet.ETH_TYPE_IP:
ip = eth.data
ipsrc = socket.inet_ntoa(ip.src)
ipdst = socket.inet_ntoa(ip.dst)
srcport = ??? ###Stuck here for source port
dstport = ??? ###Stuck here for destination port
if ip.p == dpkt.ip.IP_PROTO_TCP:
TCP = ip.data
iptype = 'tcp'
elif ip.p == dpkt.ip.IP_PROTO_UDP:
UDP = ip.data
iptype = 'udp'
len = str(ip.len)
ttl = str(ip.ttl)
###My current output
print '[' +str(datetime.datetime.utcfromtimestamp(ts))+ '] - ' \
+ipsrc+ ':' +srcport+ ' -> ' +ipdst+ ':' +dstport+ \
' ('+iptype+', len='+len+', ttl='+ttl+')'
except:
pass
样本预期输出:
[2018-08-16 02:48:10.238506] - 172.16.11.2:61016 -> 172.16.10.2:80 (tcp, len=52, ttl=63)
也许使用ip.data
获取TCP数据包和sport
and/ordport
?
ip = eth.data
if ip.p == dpkt.ip.IP_PROTO_TCP:
tcp = ip.data
print('source port: {}, dest port: {}'.format(tcp.sport, tcp.dport))
问题是您的打印语句是伪造的,但您已使用 "bare except" 隐藏了它。正是出于这个原因,在 python 中使用 bare except 被认为是非常糟糕的做法。另请参阅此问题的答案:Should I always specify an exception type in `except` statements?
具体来说,您的 print 语句试图将一个整数连接到一个无效的字符串。
所以,修复了,并且:
if ip.p == dpkt.ip.IP_PROTO_TCP:
TCP = ip.data
iptype = 'tcp'
srcport = TCP.sport
dstport = TCP.dport
elif ip.p == dpkt.ip.IP_PROTO_UDP:
UDP = ip.data
iptype = 'udp'
srcport = UDP.sport
dstport = UDP.dport
这个打印语句有效:
print("[{}] - {}:{} -> {}:{} ({}, len={}, ttl={})".format(
datetime.datetime.utcfromtimestamp(ts), ipsrc, srcport,
ipdst, dstport, iptype, len, ttl))
最后,至少,我会将您的 except 子句更改为类似这样的内容,以便将来检测此类问题:
except Exception as exc:
print("Exception: {}".format(exc))
(请注意,我在这里使用了 python3 兼容的 print function 语法,它也适用于 python2 的 print 声明.)
编辑:
我刚刚想到另一件事。如果遇到的第一个 IP 数据包既不是 TCP 也不是 UDP,srcport
和 dstport
将不会被定义,这将导致 AttributeError
异常。留给你清理。