$Id$ Guide to Hacking Tcpreplay [Note: Pay attention to the last update date at the top of this file. If it was significantly long ago, this document may be out of date.] 0. Contributing Code If you contribute code the following will happen: a) You will be given credit in the CREDITS file b) Your code will be licensed under the same license as that of tcpreplay c) You will be assigning your copyright to me I do this for a simple reason: keep things simple for me. 1. Introduction If you're reading this to find out how to add a new feature or fix a bug in tcpreplay or tcpprep, then you've come to the right place. This isn't the place to find answers regarding how to use tcpreplay, the meaning of life, etc. 2. File Layout The file layout is pretty simple: / - Code, header files, autoconf stuff /Docs - Where to find documentation /test - Test scripts and stuff which is used during 'make test' /man - Unix man pages which get copied to $MANPATH 3. Adding support for additional DLTs (Data Link Types) There are a number of files/functions that need to be touched to add support for a new DLT to tcpreplay and tcpprep. Note that for a patch to be accepted, BOTH tcpreplay and tcpprep need to be updated to support the new DLT. 3a) dlt.h Two things need to be added here: - A structure defining the header - A #define for the length of the header example for DLT_CHDLC (Cisco HDLC): /* Cisco HDLC has a simple 32 bit header */ #define CISCO_HDLC_LEN 4 struct cisco_hdlc_header { u_int16_t address; u_int16_t protocol; } 3b) tcpreplay.c You will need to edit validate_l2() to process the DLT type as defined by pcap-bpf.h which is included with libpcap. The key here is that tcpreplay needs to be able to generate a valid 802.3 ethernet frame. Basically validate_l2() has to make sure that between the existing Layer 2 header (if any) and the user supplied arguments (-2, -I, -J, -K and -k) that enough information is available. Generally this means one of: - The DLT already has a valid header - User specified their own complete header via -2 - The existing header + user specified MAC addresses are enough validate_l2() also calcuates the 'maxpacket' which is the maximum size of a packet that we can send out of the interface. Generally this is the length of the Layer 2 header + MTU. You shouldn't need to change anything here. 3c) edit_packet.c Next, you'll have to edit rewrite_l2() to add support for rewriting the Layer 2 header from your DLT to a standard 802.3 header. Note that do_packets.c will automatically fill out the source/destination MAC address if the appropriate flag is used (-I, -J, -K and -k) so there is no need to copy those values over here. 3d) tcpprep.c Look at process_raw_packets(). Should be painfully obvious what do do here. 3e) dlt_names.h Look in dlt_names.h and make sure your DLT type is listed here. Note that this file is generated by scripts/dlt2name.pl. If it's not listed here, your best bet is to edit scripts/dlt2name.pl and list it in the %known hash and then run: make dlt_names Note that editing dlt_names.h is NOT going to work, since it will get overwritten the next time it is regenerated. 4. Hacking tcprewrite tcprewrite order of execution: Figure out if input file's DLT is supported foreach (packet) { Update packet timestamp based on modifier Decide packet path via cache or CIDR lookup if (a Layer 2 header is specified) { if (existing Layer 2 header) { strip existing Layer 2 header } prepend specified Layer 2 header } if (primary path or single path) { re-write MAC addresses re-write IP addresses re-write Ports } else if (secondary path) { re-write MAC addresses re-write IP addresses re-write Ports } pad or truncate packet fix checksums write packet to outfile }