$Id: HACKING 1348 2005-06-13 06:22:17Z aturner $

                          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

If you have any questions regarding any of the three above stipulations,
feel free to email me: aturner@pobox.com


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:

/           - Base directory
/lib        - 3rd party libraries stolen verbatim
/libopts    - GNU AutoOpts code
/src        - Main code routines
/src/common - Common routines for all binaries
/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. Coding Standards
1) Indent 4 spaces using spaces, not tabs
2) Opening braces for control blocks (if, while, etc) should be on the same line
3) Opening braces for functions should be on next line
4) Use provided warnx, dbg, and errx functions provided in err.h
5) Use provided safe_strdup, safe_malloc and safe_realloc functions provided
    in common/utils.h
6) Use provided strl* functions in lib/strlcat.c and lib/strlcpy.c

[NOTE: Everything below this point is currently inaccurate.]

4. 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.

4a) 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;
}

4b) 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.

4c) 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.

4d) tcpprep.c
Look at process_raw_packets().  Should be painfully obvious what do do here.

4e) 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.

5. 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
}
