23

以前に記録したトラフィック (pcap 形式でキャプチャ) を scapy で送信しようとしています。現在、元の Ether レイヤーのストライピングに行き詰まっています。トラフィックは別のホストでキャプチャされたので、基本的に IP 層とイーサ層の src と dst の両方を変更する必要があります。IP 層を置き換えてチェックサムを再計算することはできましたが、Ether 層が問題を引き起こします。

IP および Ether レイヤー (src および dst) に変更を適用して、キャプチャ ファイルからパケットを再送信した経験がある人はいますか? また、キャプチャは Gb のかなり大きなカップルですが、そのような量のトラフィックで scapy パフォーマンスはどうですか?

4

4 に答える 4

32

この例を確認してください

from scapy.all import *
from scapy.utils import rdpcap

pkts=rdpcap("FileName.pcap")  # could be used like this rdpcap("filename",500) fetches first 500 pkts
for pkt in pkts:
     pkt[Ether].src= new_src_mac  # i.e new_src_mac="00:11:22:33:44:55"
     pkt[Ether].dst= new_dst_mac
     pkt[IP].src= new_src_ip # i.e new_src_ip="255.255.255.255"
     pkt[IP].dst= new_dst_ip
     sendp(pkt) #sending packet at layer 2

コメント:

  • rdpcap、wrpcap scapy メソッドを使用して、pcap 形式のファイルから読み書きします
  • パケットの読み取りに使用でき、このsniff(offline="filename")ような prn パラメータを使用できますsniff(offline="filename",prn=My_Function)。この場合、My_Functions はスニッフィングされたすべてのパケットに適用されます。
  • 新しい ip または mac を記述する正しい方法は、上記の例のように文字列 ex: などと見なすことip="1.1.1.1"です。
  • 例: for ループに含まれる sendp メソッドは、他のループを作成してパケットを送信するよりも低速です。
  • パフォーマンスのヒント: Python で for ループを使用するのは遅すぎます C の for ループのような速度が必要な場合は、代わりに map を使用しください
  • 上記で使用されている rdpcap はファイルを一度に読み取ります。読み取り中に使用可能なメモリが 1.5 Gb で、2、3、.. Gb ファイルを読み取っている場合、ファイルは失敗します。
  • パフォーマンスの問題が重大な場合は、winpcapを使用できますが、C でより複雑なコードを記述する必要があります。python/scapy を使用して同じタスクを実行するのは非常に簡単ですが、c よりも高速ではありません。
  • 必要なパフォーマンスのレベルに応じて、どちらを使用するかによって異なります
  • 私の推測が正しければ、この場合はビデオ ストリーム パケットを送信しています。1 メガ ピクセルのビデオを送信している場合は winpcap を使用し、他の場合は scapy を使用します (フレームあたりのサイズが小さい)
  • C/winpcap を使用する場合、pcaps を読み取り、データを変更して再送信する際に優れたパフォーマンスが得られますが、同じ問題 (大きなファイル) に注意する必要があります。これを使用するには、適切なサイズのバッファーを作成する必要があります。かなりのパフォーマンスでパケットを送信する読み取り
  • パケット サイズが一定の場合 (ほとんどの場合、これはまれなことだと思います)、使用可能なメモリを最大限に活用できるという利点があります。
  • 「プロジェクト/プログラム」全体で python/scapy を使用する場合は、C/Wincap で高性能関数を作成し、dll としてコンパイルしてから、この dll を python プログラムにインポートして、python プログラム内で使用できます。 . このようにして、素晴らしい簡単な python/Scapy の利点を得ることができ、c で特定の関数を記述するだけで、仕事をより速く完了し、コードを集中して保守しやすくすることができます。
于 2012-01-12T22:41:00.953 に答える
7

もし私があなたなら、Scapy にレイヤーを処理させEther、関数を使用させsend()ます。例えば:

ip_map = {"1.2.3.4": "10.0.0.1", "1.2.3.5": "10.0.0.2"}
for p in PcapReader("filename.cap"):
    if IP not in p:
        continue
    p = p[IP]
    # if you want to use a constant map, only let the following line
    p.src = "10.0.0.1"
    p.dst = "10.0.0.2"
    # if you want to use the original src/dst if you don't find it in ip_map
    p.src = ip_map.get(p.src, p.src)
    p.dst = ip_map.get(p.dst, p.dst)
    # if you want to drop the packet if you don't find both src and dst in ip_map
    if p.src not in ip_map or p.dst not in ip_map:
        continue
    p.src = ip_map[p.src]
    p.dst = ip_map[p.dst]
    # as suggested by @AliA, we need to let Scapy compute the correct checksum
    del(p.chksum)
    # then send the packet
    send(p)
于 2014-01-23T12:10:26.160 に答える
5

さて、scapy を使用して、次のことを思いつきました (私の Python で申し訳ありません)。うまくいけば、それは誰かを助けるでしょう。pcap ファイルからのすべてのパケットがメモリに読み込まれる、より単純なシナリオが考えられますが、これは大きなキャプチャ ファイルで問題を引き起こす可能性があります。

from scapy.all import *
global src_ip, dst_ip
src_ip = 1.1.1.1
dst_ip = 2.2.2.2
infile = "dump.pcap"

try:
    my_reader = PcapReader(infile)
    my_send(my_reader)
except IOError:
    print "Failed reading file %s contents" % infile
    sys.exit(1)

def my_send(rd, count=100):
    pkt_cnt = 0
    p_out = []

    for p in rd:
        pkt_cnt += 1
        np = p.payload
        np[IP].dst = dst_ip
        np[IP].src = src_ip
        del np[IP].chksum
        p_out.append(np)
        if pkt_cnt % count == 0:
            send(PacketList(p_out))
            p_out = []

    # Send remaining in final batch
    send(PacketList(p_out))
    print "Total packets sent %d" % pkt_cn
于 2012-01-05T14:25:03.770 に答える
0

正しいチェックサムのために、私も追加する必要がありましたdel p[UDP].chksum

于 2015-11-30T14:23:30.670 に答える