tcp流重播工具

时间:2012-05-31 13:28:04

标签: testing networking tcp network-programming

我正在寻找一种用于记录和重放TCP流的一面进行测试的工具。 我看到记录整个TCP流(服务器和客户端)的工具,用于测试防火墙等,但我正在寻找的是一种工具,它只记录客户端提交的流量(带有时间信息),然后重新提交到服务器进行测试。

5 个答案:

答案 0 :(得分:14)

由于TCP处理重传的方式,序列号,SACK和窗口化这可能是一个比你想象的更难的任务。

通常人们使用tcpreplay进行数据包重播;但是,doesn't support synchronizing TCP sequence numbers。由于您需要具有双向TCP流(并且这需要同步seq编号),请使用以下选项之一:

  1. 如果这是一个非常交互式的客户端/服务器协议,您可以使用scapy去除流的TCP内容,解析时间和交互性。接下来使用此信息,打开服务器的新TCP套接字并将该数据反序列化为新的TCP套接字。如果您遇到TCP重新传输和窗口动态,使用scapy解析原始流可能会非常棘手。将字节写入新的TCP套接字不需要自己处理序列编号......操作系统会处理这个问题。

  2. 如果这是一个简单的流,你可以没有计时(或想手动插入时间信息),你可以使用wireshark从TCP蒸汽中获取原始字节而不用担心关于使用scapy进行解析。获得原始字节后,将这些字节写入新的TCP套接字(根据需要考虑交互性)。将字节写入新的TCP套接字不需要自己处理序列编号......操作系统会处理这个问题。

  3. 如果您的流是严格的文本(但不是html或xml)命令(例如telnet会话),则类似Expect的解决方案可能比上述解析更容易。在此解决方案中,您不会直接从代码中打开TCP套接字,使用期望spawn telnet(或其他)会话,并使用send / expect重播文本命令。您期望的库/底层操作系统会处理seq编号。

  4. 如果您正在测试网络服务,我怀疑模拟真实的网络客户端点击SeleniumSplinter的链接要容易得多。您的http库/底层操作系统将负责新流中的seq编号。

答案 1 :(得分:3)

查看WirePlay code.google.com/p/wireplaygithub.com/abhisek/wireplay,它承诺重播捕获的TCP会话的客户端或服务器端,并根据需要修改所有SYN / ACK序列号。

我不知道是否有可用的二进制版本,你需要自己编译。

注意我还没有尝试过这个,但我正在研究它。

答案 2 :(得分:2)

是的,实施这样的工具是一项艰巨的任务。 两年前我开始实现这种工具,现在该工具已经成熟。 尝试一下,也许你会发现它是你正在寻找的工具。

https://github.com/wangbin579/tcpcopy

答案 3 :(得分:2)

我想要类似的东西,所以我用scapy做了一点,然后提出了一个适合我的解决方案。我的目标是重播捕获的pcap文件的客户端部分。我有兴趣从服务器获得响应 - 不一定是时间安排。下面是我的scapy解决方案 - 它绝不是测试或完成,但它做了我想要它做的事情。希望它是如何使用scapy重放TCP流的一个很好的例子。

from scapy.all import *
import sys

#NOTE - This script assumes that there is only 1 TCP stream in the PCAP file and that 
# you wish to replay the role of the client

#acks
ACK = 0x10
#client closing the connection
RSTACK = 0x14

def replay(infile, inface):
    recvSeqNum = 0
    first = True
    targetIp = None
    #send will put the correct src ip and mac in
    #this assumes that the client portion of the stream is being replayed
    for p in rdpcap(infile):
        if 'IP' in p and 'TCP' in p:
            ip = p[IP]
            eth = p[Ether]
            tcp = p[TCP]
            if targetIp == None:
                #figure out the target ip we're interested in
                targetIp = ip.dst
                print(targetIp)
            elif ip.dst != targetIp:
                # don't replay a packet that isn't to our target ip
                continue
            # delete checksums so that they are recalculated
            del ip.chksum
            del tcp.chksum
            if tcp.flags == ACK or tcp.flags == RSTACK:
                tcp.ack = recvSeqNum+1
                if first or tcp.flags == RSTACK:
                    # don't expect a response from these
                    sendp(p, iface=inface)
                    first=False
                    continue

            rcv = srp1(p, iface=inface)
            recvSeqNum = rcv[TCP].seq

def printUsage(prog):
    print("%s <pcapPath> <interface>" % prog)

if __name__ == "__main__":
    if 3 != len(sys.argv):
        printUsage(sys.argv[0])
        exit(1)
    replay(sys.argv[1], sys.argv[2])

答案 4 :(得分:2)

记录完整TCP客户端/服务器通信的数据包捕获。然后,您可以使用tcpliveplay仅将通信的客户端重播到真实服务器。 tcpliveplay将生成新的序列号,IP地址,MAC地址等,以便通信正常流动。