Annotation of embedaddon/libnet/doc/DESIGN_NOTES, revision 1.1.1.1

1.1       misho       1: ===============================================================================
                      2:     $Id: DESIGN_NOTES,v 1.3 2004/01/17 07:51:19 mike Exp $
                      3:     LIBNET 1.1 (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
                      4:                                http://www.packetfactory.net/libnet
                      5: ===============================================================================
                      6: 
                      7: 
                      8:     DESIGN NOTES
                      9: 
                     10:     In order to remove most of the decisions a user had to make (how much
                     11:     memory to allocate for a packet, where to build the packet headers, where
                     12:     to do the checksums, how to inject the packet, etc) I decided to move ALL
                     13:     of that logic into the library, behind the scenes.  To initialize 
                     14:     things and get an initial libnet context, the applications programmer
                     15:     calls:
                     16:  
                     17:         libnet_t *l;
                     18:         l = libnet_init(INJECTION_TYPE, PROTOCOL, DEVICE, ERRBUFFER);
                     19:  
                     20:     where:
                     21: 
                     22:     INJECTION_TYPE = LIBNET_RAW4 (ipv4 raw socket)
                     23:                      LIBNET_RAW6 (ipv6 raw socket)
                     24:                      LIBNET_LINK (link-layer socket)
                     25:                      LIBNET_RAW4_ADV (advanced mode)
                     26:                      LIBNET_RAW6_ADV (advanced mode)
                     27:                      LIBNET_LINK_ADV (advanced mode)
                     28:  
                     29:     PROTOCOL =       IP protocol to be used for the raw socket.  This is
                     30:                      ignored for the link-layer, and almost always 
                     31:                      IPPROTO_RAW for ipv4.
                     32:  
                     33:     DEVICE =         The canoical name of the device, used only with the link
                     34:                      layer stuff.  For ipv4 raw socket, you can leave this
                     35:                      NULL.  If it's NULL with the link-layer, libnet will try
                     36:                      to find a suitable device.
                     37:  
                     38:     ERRBUFFER =      Until we have our libnet context l, this is where
                     39:                      errors will be.
                     40:  
                     41:     Inside of this newly created context we have a ton of stuff including a
                     42:     file descriptor for the packet device the injection type, the device name
                     43:     (if applicable) a pointer to the libnet protocol block structure and some
                     44:     other ancillary data.
                     45:  
                     46:     Additionally, we will soon be supporting context manipulation functions
                     47:     that will allow the user to set certain flags inside the context.  This
                     48:     interface will be akin to libnet_toggle_checksum() for those of you who
                     49:     care.
                     50: 
                     51:     When a packet is first constructed, the protocol block (pblock) stuff comes
                     52:     into play.  On the outside, to an applications programmer, a packet is
                     53:     constructed more or less like normal (with a few notable exceptions):
                     54:  
                     55:         libnet_ptag_t ip_tag;
                     56:         ip_tag = libnet_build_ipv4(
                     57:                         LIBNET_UDP_H,
                     58:                         0,
                     59:                         242,
                     60:                         0,
                     61:                         64,
                     62:                         IPPROTO_UDP,
                     63:                         0,              /* NEW: checksum */
                     64:                         src_ip,
                     65:                         dst_ip,
                     66:                         NULL,
                     67:                         0,
                     68:                         l,              /* NEW: libnet context */
                     69:                         0               /* NEW: libnet ptag */
                     70:                         );
                     71:  
                     72:     The checksum allows an applications programmer to decide if he wants to
                     73:     specify his own random value (useful in NIDS fooling) or precompute the
                     74:     sum elsewhere, or leave it zero and by default libnet will take care of it
                     75:     (although this is over-ridable).  The libnet context is the opague
                     76:     pointer we allocated earlier and will show up in just about every libnet
                     77:     function call from here on out.  The libnet ptag is a way to reference an
                     78:     ALREADY BUILT protocol block.  This is necessary if you want to change 
                     79:     some values of a header inside of a packet injection loop.
                     80:  
                     81:     So, when you call a build function, internally, it's a completely new
                     82:     system.  If the item you're constructing is NEW, a new pblock will be
                     83:     allocated and linked onto the end of the list.  It may be helpful to think
                     84:     of this as a "protocol stack" because you MUST build your packets IN 
                     85:     ORDER, from the top of the protocol stack on down (i.e.: tcp -> ip ->
                     86:     ethernet).  Once you build a new protocol block, it's "pushed down on the
                     87:     stack" and you move on to the next.  However, this analogy breaks down 
                     88:     because you can modify any one of these items and when they're assembled
                     89:     for the final packet, libnet starts at the head of the list.  It may be
                     90:     MORE helpful to think of the pblock chain as a doubly linked FIFO 
                     91:     queue, because that's what it is. :)
                     92:  
                     93:     For example:
                     94:  
                     95:         libnet_ptag_t 1;
                     96:         libnet_ptag_t 2;
                     97:         libnet_ptag_t 3;
                     98:  
                     99:         1 = libnet_build_data(blah, l, 0);
                    100:         2 = libnet_build_tcp(blah, l, 0);
                    101:         3 = libnet_build_ipv4(blah, l, 0);
                    102:  
                    103:     Will result in:
                    104:                           ----------      ----------      ----------
                    105:     l->protocol_blocks--->|  data  |----->|  tcp   |----->|   ip   |
                    106:                           | pblock |<-----| pblock |<-----| pblock |----|
                    107:                         --| ptag: 1|      | ptag: 2|      | ptag: 3|    |
                    108:                         | ----------      ----------      ----------    v
                    109:                         |                                             -----
                    110:                         |------------------------------------------->  ---
                    111:                                                                         -
                    112:  
                    113:     To access and change the ip header, an additional call to libnet_build_ipv4
                    114:     with the ptag argument would be made:
                    115:  
                    116:         libnet_build_ipv4(blah..., l, 3);
                    117:  
                    118:     Note that the ptag DOES NOT CHANGE.  Once a pblock is built, its tag is
                    119:     set in stone.
                    120:  
                    121:     When it comes time to write the packet to the wire,
                    122:     libnet_pblock_coalesce() is called to assemble the packet fragments.
                    123:  
                    124:         1) Gather up all of the pblock sizes in order to allocate one
                    125:            contiguous block of memory.
                    126:         2) Copy over the packet fragments.
                    127:         3) Check each pblock to see which items need checksums, then perform
                    128:            that checksum over each portion (the entire packet is needed for
                    129:            some checksums).
                    130:  
                    131:     So that's a quick description of what's going on under the hood.  There's
                    132:     more, but this should be enough to get you started.
                    133: 
                    134: EOF

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>