File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / doc / DESIGN_NOTES
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:14:23 2012 UTC (13 years, 4 months ago) by misho
Branches: libnet, MAIN
CVS tags: v1_1_6p5, v1_1_6p4, v1_1_6p0, v1_1_6, v1_1_2_1, HEAD
libnet

    1: ===============================================================================
    2:     $Id: DESIGN_NOTES,v 1.1.1.1 2012/02/21 22:14:23 misho 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>