1

大家好,这是我第一次使用 Python 作为编程语言进行 PCAP 编程,这是针对大学的一项任务,除了一个小细节外,我几乎已经获得了完成任务所需的一切。

我只需要获取与 IP 地址关联的源端口号和目标端口号(例如 HTTP 端口 80)的输出。

我很高兴答案是指向正确方向的指针,可以帮助我自己解决问题。否则,如果它更容易被回答,我想要一个关于使用什么以及它如何解决问题的基本解释,这样当我在我的学习和研究中进行更多的未来 PCAP 编程时,我可以更好地理解它。

这是在运行 FreeBSD 10.3 的 Unix 系统上使用的

我尝试过使用 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)
4

2 回答 2

0

问题是您的打印语句是伪造的,但是您已经用“裸例外”隐藏了它。正是由于这个原因,在 python 中使用裸的 except 被认为是非常糟糕的做法。另请参阅此问题的答案:我是否应该始终在 `except` 语句中指定异常类型?

具体来说,您的 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函数语法,它也适用于 python2 的 print语句。)

编辑:
我刚想到另一件事。如果遇到的第一个 IP 数据包既不是 TCP 也不是 UDP,srcport并且dstport不会被定义,这将导致AttributeError异常。留给你清理。

于 2019-04-26T17:09:58.147 回答
0

也许用于ip.data获取 TCP 数据包sport和/或dport

ip = eth.data

if ip.p == dpkt.ip.IP_PROTO_TCP:
    tcp = ip.data
    print('source port: {}, dest port: {}'.format(tcp.sport, tcp.dport))
于 2019-04-25T16:38:53.780 回答