2

Scapy の関数を使用sendして、ルーターで ICMP パケットを生成するデータ パケットを送信し、それらの ICMP パケットをtcpdump子プロセスとして起動してダンプします。

次に、scapy の組み込みrdpcap関数を使用して、これらの ICMP パケットをプログラムに読み込みます。

さて、時々何かを台無しにすることが判明しrdpcap、キャプチャしたパケットをのぞき見したいとすぐに、次のように返されます。

(InteractiveConsole)
>>> icmpPackets
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/scapy/plist.py", line 57, in __repr__
    if self._elt2pkt(r).haslayer(p):
AttributeError: 'NoneType' object has no attribute 'haslayer'

次に、同じrdpcap引数で再度呼び出すだけで、すべてが正常に戻ります。

>>> icmpPackets = rdpcap(tcpdumpFileName)
>>> icmpPackets
<icmpPackets.cap: TCP:0 UDP:0 ICMP:1428 Other:1>

これはバグですよね?

編集: OK、そのエラーが発生する前に私が行うことの 1 つは次のとおりです。これはあまり正統的ではないかもしれませんが、パケットを偽造するときにイーサネット層は必要ありません。これらの 2 行を削除すると、そのようなエラーは発生しなくなります。

for i in range(len(icmpPackets)):
        icmpPackets[i] = icmpPackets[i].getlayer(IP)

私は以前にこれを他の場所で行いましたが、問題は発生しませんでした。ここで何が起こっているのですか?

4

1 に答える 1

1

やあ、

scapyではなくtcpdumpでトラフィックを盗聴する理由がよくわかりませんが、とにかく...あなたの問題はScapyのバグではなく、コードにあります。各パケットを、パケットにレイヤーがない場合.getlayer(IP)に返されるものに置き換えています(たとえば、パケット)。したがって、後者の例外が発生します。NoneIPARP

交換した方がいいと思います

icmpPackets = rdpcap(tcpdumpFileName)
for i in range(len(icmpPackets)):
    icmpPackets[i] = icmpPackets[i].getlayer(IP)

icmpPackets = PacketList([p[IP] for p in PcapReader(tcpdumpFileName) if IP in p])

まず第一に、より「Pythonic」だと思います。さらに、IPレイヤーなしでパケットを削除することで問題を解決します。Etherまたは、レイヤーなしですべてのパケットを取得する場合は、次を使用することもできます。

icmpPackets = PacketList([p.payload for p in PcapReader(tcpdumpFileName)])

さらに、tcpdump で BPF フィルタを使用してフィルタリングすることもできます (パケットicmpだけが必要な場合ICMP)。

于 2014-01-22T21:19:53.290 に答える