- All Implemented Interfaces:
Closeable, Flushable, AutoCloseable
The source and dest "IP" and "port" are fake but are generated from the hashes of the Destinations and stream ID's, so they will be consistent. The local "IP" will always be of the form 127.0.x.y Initial IP for a conn will be 127.0.0.0 for the local and 0.0.0.0 for the remote.
Reference: http://wiki.wireshark.org/Development/LibpcapFileFormat
The Jpcap library was close to what I want, but it requires you to instantiate a "captor" before you can write a file, and it requires a native lib to do so, and even then, it only wants to read the file, not write it.
We even calculate a correct TCP header checksum to keep the tools happy. We don't, however, convert I2P-style sequence numbers, which count packets, to TCP-style byte counts. We don't track a lowest-acked-thru byte count atm, really.
We do represent the window size in bytes though, so that's real confusing.
This is designed to debug the streaming lib, but there are not log calls for every single packet - pings and pongs, and various odd cases where received packets are dropped, are not logged.
Yes we could dump it natively and write a wireshark dissector. That sounds hard. And we wouldn't get the TCP stream analysis built into the tools.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classBuilder for TCP option blocks in the pcap output.Field Summary
FieldsModifier and TypeFieldDescriptionprivate final I2PAppContextThe app context.private final OutputStreamStream the pcap records are written to.private final LogLogger for the pcap writer.private static final byte[]Big-endian pcap global header, see file format ref - 24 bytes.private static final byte[]First half of the fake IP header.private static final byte[]Second half of the fake IP header.private static final byte[]Dummy MAC addresses, IPv4 ethertype.private static final intOptions - give our custom ones some mnemonics.private static final intMax # of streaming lib payload bytes to dump.private static final byte[]Placeholder address of our side.private static final byteOption marking the end of the options.private static final byteOption carrying the sender's port.private static final byteOption carrying the maximum segment size.private static final byteOption of the negative ack.private static final byteOption carrying our send delay.private static final byteOption of the ping request.private static final byteOption of the ping reply.private static final byteOption carrying our receive delay.private static final byteOption carrying the signature.private static final byteOption requesting the signature.private static final byte[]Placeholder address of an unknown peer.Constructor Summary
ConstructorsConstructorDescriptionPcapWriter(I2PAppContext ctx, String file) Creates a new PcapWriter that writes to the specified file in the log directory.Method Summary
Modifier and TypeMethodDescriptionvoidclose()Closes the output stream, flushing any buffered data.voidflush()Flushes any buffered data to the underlying output stream.private static longCalculate the lowest sequence number that has been acked through.private static intupdate(int checksum, byte[] b) One's complement 2-byte checksum update.private static intupdate(int checksum, byte[] b, int len) One's complement 2-byte checksum update.voidwrite(PacketLocal pkt) Write an outbound packet to the pcap file.voidwrite(Packet pkt, Connection con) Write an inbound packet to the pcap file.private voidwrt(Packet pkt, Connection con, boolean isInbound) Write a packet to the pcap file in the proper format.
Field Details
FILE_HEADER
private static final byte[] FILE_HEADERBig-endian pcap global header, see file format ref - 24 bytes.MAC_HEADER
private static final byte[] MAC_HEADERDummy MAC addresses, IPv4 ethertype.IP_HEADER_1
private static final byte[] IP_HEADER_1First half of the fake IP header.IP_HEADER_2
private static final byte[] IP_HEADER_2Second half of the fake IP header.UNK_IP
private static final byte[] UNK_IPPlaceholder address of an unknown peer.MY_UNK_IP
private static final byte[] MY_UNK_IPPlaceholder address of our side.MAX_PAYLOAD_BYTES
private static final int MAX_PAYLOAD_BYTESMax # of streaming lib payload bytes to dump.- See Also:
MAX_OPTION_LEN
private static final int MAX_OPTION_LENOptions - give our custom ones some mnemonics.- See Also:
OPTION_END
private static final byte OPTION_ENDOption marking the end of the options.- See Also:
OPTION_MSS
private static final byte OPTION_MSSOption carrying the maximum segment size.- See Also:
OPTION_PING
OPTION_PONG
OPTION_SIGREQ
private static final byte OPTION_SIGREQOption requesting the signature.- See Also:
OPTION_SIG
OPTION_RDELAY
private static final byte OPTION_RDELAYOption carrying our receive delay.- See Also:
OPTION_ODELAY
private static final byte OPTION_ODELAYOption carrying our send delay.- See Also:
OPTION_FROM
private static final byte OPTION_FROMOption carrying the sender's port.- See Also:
OPTION_NACK
_fos
Stream the pcap records are written to._context
The app context._log
Logger for the pcap writer.
Constructor Details
PcapWriter
Creates a new PcapWriter that writes to the specified file in the log directory.- Parameters:
ctx- the application contextfile- the filename to write (relative to the log directory)- Throws:
IOException- if the file cannot be opened or the header cannot be written
Method Details
close
public void close()Closes the output stream, flushing any buffered data. Errors during close are silently ignored.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable
flush
write
Write an outbound packet to the pcap file.- Parameters:
pkt- the outbound packet to write- Throws:
IOException- if the packet cannot be written
write
Write an inbound packet to the pcap file.- Parameters:
pkt- the inbound packet to writecon- the connection, may be null- Throws:
IOException- if the packet cannot be written
wrt
private void wrt(Packet pkt, Connection con, boolean isInbound) throws IOException, DataFormatException Write a packet to the pcap file in the proper format.- Parameters:
pkt- the packet to writecon- the connection, may be nullisInbound- true if the packet is inbound- Throws:
IOException- if the packet cannot be writtenDataFormatException- if the packet data is malformed
getLowestAckedThrough
Calculate the lowest sequence number that has been acked through.- Parameters:
pkt- the packet containing ack information- Returns:
- the lowest acked-through sequence number (at least 0)
update
private static int update(int checksum, byte[] b) One's complement 2-byte checksum update.- Parameters:
checksum- the running checksumb- the data to incorporate- Returns:
- the updated checksum
update
private static int update(int checksum, byte[] b, int len) One's complement 2-byte checksum update.- Parameters:
checksum- the running checksumb- the data to incorporatelen- the number of bytes to use from b- Returns:
- the updated checksum