I'm looking for a tool for recording and replaying one side of a TCP stream for testing. I see tools which record the entire TCP stream (both server and client) for testing firewalls and such, but what I'm looking for is a tool which would record just the traffic submitted by the client (with timing information) and then resubmit it to the server for testing.
问题:
回答1:
Due to the way that TCP handles retransmissions, sequence numbers, SACK
and windowing this could be a more difficult task than you imagine.
Typically people use tcpreplay for packet replay; however, it doesn't support synchronizing TCP sequence numbers. Since you need to have a bidirectional TCP stream, (and this requires synchronization of seq numbering) use one of the following options:
If this is a very interactive client / server protocol, you could use
scapy
to strip out the TCP contents of your stream, parse for timing and interactivity. Next use this information, open a new TCP socket to your server and deserialize that data into the new TCP socket. Parsing the original stream withscapy
could be tricky, if you run into TCP retransmissions and windowing dynamics. Writing the bytes into a new TCP socket will not require dealing with sequence numbering yourself... the OS will take care of that.If this is a simple stream and you could do without timing (or want to insert timing information manually), you can use wireshark to get the raw bytes from a TCP steam without worrying about parsing with
scapy
. After you have the raw bytes, write these bytes into a new TCP socket (accounting for interactivity as required). Writing the bytes into a new TCP socket will not require dealing with sequence numbering yourself... the OS will take care of that.If your stream is strictly text (but not html or xml) commands, such as a telnet session, an Expect-like solution could be easier than the aforementioned parsing. In this solution, you would not open a TCP socket directly from your code, using expect to
spawn
a telnet (or whatever) session and replay the text commands withsend
/expect
. Your expect library / underlying OS would take care of seq numbering.If you're testing a web service, I suspect it would be much easier to simulate a real web client clicking through links with
Selenium
orSplinter
. Your http library / underlying OS would take care of seq numbering in the new stream.
回答2:
Take a look at WirePlay code.google.com/p/wireplay or github.com/abhisek/wireplay which promises to replay either client or server side of a captured TCP session with modification of all the SYN/ACK sequence numbers as required.
I don't know if there are any binary builds available, you'll need to compile it yourself.
Note I have not tried this myself yet, but am looking into it.
回答3:
Yes, it is a difficult task to implement such a tool. I started to implement this kind of tool two years ago and the tool is mature now. Try it and maybe you will find that it is the tool that you are looking for.
https://github.com/wangbin579/tcpcopy
回答4:
I wanted something similar so I worked with scapy for a bit and came up with a solution that worked for me. My goal was to replay the client portion of a captured pcap file. I was interested in getting responses from the server - not necessarily with timings. Below is my scapy solution - it is by no means tested or complete but it did what I wanted it to do. Hopefully it's a good example of how to replay a TCP stream using scapy.
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])
回答5:
Record a packet capture of the full TCP client/server communication. Then, you can use tcpliveplay to replay just the client side of the communication to a real server. tcpliveplay will generate new sequence numbers, IP addresses, MAC addresses, etc, so the communication will flow properly.