Blame doc/DESIGN_NOTES

Packit 03b34a
===============================================================================
Packit 03b34a
    $Id: DESIGN_NOTES,v 1.3 2004/01/17 07:51:19 mike Exp $
Packit 03b34a
    LIBNET 1.1 (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
Packit 03b34a
                               http://www.packetfactory.net/libnet
Packit 03b34a
===============================================================================
Packit 03b34a
Packit 03b34a
Packit 03b34a
    DESIGN NOTES
Packit 03b34a
Packit 03b34a
    In order to remove most of the decisions a user had to make (how much
Packit 03b34a
    memory to allocate for a packet, where to build the packet headers, where
Packit 03b34a
    to do the checksums, how to inject the packet, etc) I decided to move ALL
Packit 03b34a
    of that logic into the library, behind the scenes.  To initialize 
Packit 03b34a
    things and get an initial libnet context, the applications programmer
Packit 03b34a
    calls:
Packit 03b34a
 
Packit 03b34a
        libnet_t *l;
Packit 03b34a
        l = libnet_init(INJECTION_TYPE, PROTOCOL, DEVICE, ERRBUFFER);
Packit 03b34a
 
Packit 03b34a
    where:
Packit 03b34a
Packit 03b34a
    INJECTION_TYPE = LIBNET_RAW4 (ipv4 raw socket)
Packit 03b34a
                     LIBNET_RAW6 (ipv6 raw socket)
Packit 03b34a
                     LIBNET_LINK (link-layer socket)
Packit 03b34a
                     LIBNET_RAW4_ADV (advanced mode)
Packit 03b34a
                     LIBNET_RAW6_ADV (advanced mode)
Packit 03b34a
                     LIBNET_LINK_ADV (advanced mode)
Packit 03b34a
 
Packit 03b34a
    PROTOCOL =       IP protocol to be used for the raw socket.  This is
Packit 03b34a
                     ignored for the link-layer, and almost always 
Packit 03b34a
                     IPPROTO_RAW for ipv4.
Packit 03b34a
 
Packit 03b34a
    DEVICE =         The canoical name of the device, used only with the link
Packit 03b34a
                     layer stuff.  For ipv4 raw socket, you can leave this
Packit 03b34a
                     NULL.  If it's NULL with the link-layer, libnet will try
Packit 03b34a
                     to find a suitable device.
Packit 03b34a
 
Packit 03b34a
    ERRBUFFER =      Until we have our libnet context l, this is where
Packit 03b34a
                     errors will be.
Packit 03b34a
 
Packit 03b34a
    Inside of this newly created context we have a ton of stuff including a
Packit 03b34a
    file descriptor for the packet device the injection type, the device name
Packit 03b34a
    (if applicable) a pointer to the libnet protocol block structure and some
Packit 03b34a
    other ancillary data.
Packit 03b34a
 
Packit 03b34a
    Additionally, we will soon be supporting context manipulation functions
Packit 03b34a
    that will allow the user to set certain flags inside the context.  This
Packit 03b34a
    interface will be akin to libnet_toggle_checksum() for those of you who
Packit 03b34a
    care.
Packit 03b34a
Packit 03b34a
    When a packet is first constructed, the protocol block (pblock) stuff comes
Packit 03b34a
    into play.  On the outside, to an applications programmer, a packet is
Packit 03b34a
    constructed more or less like normal (with a few notable exceptions):
Packit 03b34a
 
Packit 03b34a
        libnet_ptag_t ip_tag;
Packit 03b34a
        ip_tag = libnet_build_ipv4(
Packit 03b34a
                        LIBNET_UDP_H,
Packit 03b34a
                        0,
Packit 03b34a
                        242,
Packit 03b34a
                        0,
Packit 03b34a
                        64,
Packit 03b34a
                        IPPROTO_UDP,
Packit 03b34a
                        0,              /* NEW: checksum */
Packit 03b34a
                        src_ip,
Packit 03b34a
                        dst_ip,
Packit 03b34a
                        NULL,
Packit 03b34a
                        0,
Packit 03b34a
                        l,              /* NEW: libnet context */
Packit 03b34a
                        0               /* NEW: libnet ptag */
Packit 03b34a
                        );
Packit 03b34a
 
Packit 03b34a
    The checksum allows an applications programmer to decide if he wants to
Packit 03b34a
    specify his own random value (useful in NIDS fooling) or precompute the
Packit 03b34a
    sum elsewhere, or leave it zero and by default libnet will take care of it
Packit 03b34a
    (although this is over-ridable).  The libnet context is the opague
Packit 03b34a
    pointer we allocated earlier and will show up in just about every libnet
Packit 03b34a
    function call from here on out.  The libnet ptag is a way to reference an
Packit 03b34a
    ALREADY BUILT protocol block.  This is necessary if you want to change 
Packit 03b34a
    some values of a header inside of a packet injection loop.
Packit 03b34a
 
Packit 03b34a
    So, when you call a build function, internally, it's a completely new
Packit 03b34a
    system.  If the item you're constructing is NEW, a new pblock will be
Packit 03b34a
    allocated and linked onto the end of the list.  It may be helpful to think
Packit 03b34a
    of this as a "protocol stack" because you MUST build your packets IN 
Packit 03b34a
    ORDER, from the top of the protocol stack on down (i.e.: tcp -> ip ->
Packit 03b34a
    ethernet).  Once you build a new protocol block, it's "pushed down on the
Packit 03b34a
    stack" and you move on to the next.  However, this analogy breaks down 
Packit 03b34a
    because you can modify any one of these items and when they're assembled
Packit 03b34a
    for the final packet, libnet starts at the head of the list.  It may be
Packit 03b34a
    MORE helpful to think of the pblock chain as a doubly linked FIFO 
Packit 03b34a
    queue, because that's what it is. :)
Packit 03b34a
 
Packit 03b34a
    For example:
Packit 03b34a
 
Packit 03b34a
        libnet_ptag_t 1;
Packit 03b34a
        libnet_ptag_t 2;
Packit 03b34a
        libnet_ptag_t 3;
Packit 03b34a
 
Packit 03b34a
        1 = libnet_build_data(blah, l, 0);
Packit 03b34a
        2 = libnet_build_tcp(blah, l, 0);
Packit 03b34a
        3 = libnet_build_ipv4(blah, l, 0);
Packit 03b34a
 
Packit 03b34a
    Will result in:
Packit 03b34a
                          ----------      ----------      ----------
Packit 03b34a
    l->protocol_blocks--->|  data  |----->|  tcp   |----->|   ip   |
Packit 03b34a
                          | pblock |<-----| pblock |<-----| pblock |----|
Packit 03b34a
                        --| ptag: 1|      | ptag: 2|      | ptag: 3|    |
Packit 03b34a
                        | ----------      ----------      ----------    v
Packit 03b34a
                        |                                             -----
Packit 03b34a
                        |------------------------------------------->  ---
Packit 03b34a
                                                                        -
Packit 03b34a
 
Packit 03b34a
    To access and change the ip header, an additional call to libnet_build_ipv4
Packit 03b34a
    with the ptag argument would be made:
Packit 03b34a
 
Packit 03b34a
        libnet_build_ipv4(blah..., l, 3);
Packit 03b34a
 
Packit 03b34a
    Note that the ptag DOES NOT CHANGE.  Once a pblock is built, its tag is
Packit 03b34a
    set in stone.
Packit 03b34a
 
Packit 03b34a
    When it comes time to write the packet to the wire,
Packit 03b34a
    libnet_pblock_coalesce() is called to assemble the packet fragments.
Packit 03b34a
 
Packit 03b34a
        1) Gather up all of the pblock sizes in order to allocate one
Packit 03b34a
           contiguous block of memory.
Packit 03b34a
        2) Copy over the packet fragments.
Packit 03b34a
        3) Check each pblock to see which items need checksums, then perform
Packit 03b34a
           that checksum over each portion (the entire packet is needed for
Packit 03b34a
           some checksums).
Packit 03b34a
 
Packit 03b34a
    So that's a quick description of what's going on under the hood.  There's
Packit 03b34a
    more, but this should be enough to get you started.
Packit 03b34a
Packit 03b34a
EOF