Scapy and tcpreplay: bypass temporary file for performance

前端 未结 1 1891
暗喜
暗喜 2021-01-19 09:34

Scapy has a sendpfast function that sends packets using tcpreplay. However, this function first creates a temporary pcap file and then calls tcpreplay on that.

1条回答
  •  囚心锁ツ
    2021-01-19 10:16

    Not sure whether or not avoiding temporary file will be enough, but still, here is a way:

    #! /usr/bin/env python
    
    from scapy.all import *
    
    def pkt2pcap(p):
            sec = int(p.time)
            usec = int(round((p.time-sec)*1000000))
            s = str(p)
            caplen = len(s)
            return struct.pack("IIII", sec, usec, caplen, caplen) + s
    
    # adapted from Scapy's sendpfast
    def mysendpfast(x, pps=None, mbps=None, realtime=None, loop=0, file_cache=False, iface=None):
        """Send packets at layer 2 using tcpreplay for performance
        pps:  packets per second
        mpbs: MBits per second
        realtime: use packet's timestamp, bending time with realtime value
        loop: number of times to process the packet list
        file_cache: cache packets in RAM instead of reading from disk at each iteration
        iface: output interface """
        if iface is None:
            iface = conf.iface
        argv = [conf.prog.tcpreplay, "--intf1=%s" % iface ]
        if pps is not None:
            argv.append("--pps=%i" % pps)
        elif mbps is not None:
            argv.append("--mbps=%i" % mbps)
        elif realtime is not None:
            argv.append("--multiplier=%i" % realtime)
        else:
            argv.append("--topspeed")
        if loop:
            argv.append("--loop=%i" % loop)
            if file_cache:
                argv.append("--enable-file-cache")
        argv.append("-")
        try:
            f = subprocess.Popen(argv, stdin=subprocess.PIPE)
            # PCAP header
            p = x.next()
            f.stdin.write(struct.pack("IHHIIII", 0xa1b2c3d4L,
                                      2, 4, 0, 0, MTU,
                                      conf.l2types[p.__class__]))
            # Let's send
            f.stdin.write(pkt2pcap(p))
            for p in x:
                f.stdin.write(pkt2pcap(p))
            f.stdin.close()
            f.communicate()
        except KeyboardInterrupt:
            log_interactive.info("Interrupted by user")
        except Exception,e:
            log_interactive.error("while trying to exec [%s]: %s" % (argv[0],e))
    

    0 讨论(0)
提交回复
热议问题