1 """Tool to convert Envoy tap trace format to PCAP.
3 Uses od and text2pcap (part of Wireshark) utilities to translate the Envoy
4 tap trace proto format to a PCAP file suitable for consuming in Wireshark
5 and other tools in the PCAP ecosystem. The TCP stream in the output PCAP is
6 synthesized based on the known IP/port/timestamps that Envoy produces in its
7 tap files; it is not a literal wire tap.
11 bazel run @envoy_api//tools:tap2pcap <tap .pb/.pb_text> <pcap path>
14 - IPv6 PCAP generation has malformed TCP packets. This appears to be a text2pcap
18 - Figure out IPv6 PCAP issue above, or file a bug once the root cause is clear.
20 from __future__
import print_function
25 import subprocess
as sp
31 from envoy.data.tap.v2alpha
import wrapper_pb2
36 dump.write(
'%s\n' % direction)
38 adjusted_dt = timestamp.ToDatetime() - datetime.timedelta(seconds=time.altzone)
39 dump.write(
'%s\n' % adjusted_dt)
40 od = sp.Popen([
'od',
'-Ax',
'-tx1',
'-v'], stdout=sp.PIPE, stdin=sp.PIPE, stderr=sp.PIPE)
41 packet_dump = od.communicate(data)[0]
42 dump.write(packet_dump.decode())
43 return dump.getvalue()
47 wrapper = wrapper_pb2.TraceWrapper()
48 if tap_path.endswith(
'.pb_text'):
49 with open(tap_path,
'r')
as f:
50 text_format.Merge(f.read(), wrapper)
52 with open(tap_path,
'r')
as f:
53 wrapper.ParseFromString(f.read())
55 trace = wrapper.socket_buffered_trace
56 local_address = trace.connection.local_address.socket_address.address
57 local_port = trace.connection.local_address.socket_address.port_value
58 remote_address = trace.connection.remote_address.socket_address.address
59 remote_port = trace.connection.remote_address.socket_address.port_value
62 for event
in trace.events:
63 if event.HasField(
'read'):
64 dumps.append(
dump_event(
'I', event.timestamp, event.read.data.as_bytes))
65 elif event.HasField(
'write'):
66 dumps.append(
dump_event(
'O', event.timestamp, event.write.data.as_bytes))
70 socket.inet_pton(socket.AF_INET6, local_address)
76 'text2pcap',
'-D',
'-t',
'%Y-%m-%d %H:%M:%S.',
'-6' if ipv6
else '-4',
77 '%s,%s' % (remote_address, local_address),
'-T',
78 '%d,%d' % (remote_port, local_port),
'-', pcap_path
80 text2pcap = sp.Popen(text2pcap_args, stdout=sp.PIPE, stdin=sp.PIPE)
81 text2pcap.communicate(
'\n'.join(dumps).
encode())
84 if __name__ ==
'__main__':
85 if len(sys.argv) != 3:
86 print(
'Usage: %s <tap .pb/.pb_text> <pcap path>' % sys.argv[0])