File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / doc / PACKET_BUILDING
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:14:23 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: ===============================================================================
    2:     $Id: PACKET_BUILDING,v 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:     ADDING A NEW PACKET BUILDER
    9: 
   10:     Adding a new packet building module is usually pretty simple.  It depends
   11:     completely on the complexity of the protocol.  The following document
   12:     shows you how to add a packet builder for a simple protocol with a
   13:     static header size, but these concepts can be extended to a complex 
   14:     protocol also.
   15: 
   16:     1) Start by defining your protocol header format in libnet-headers.h:
   17: 
   18:     #define LIBNET_XXX_H 0xSIZE
   19: 
   20:     struct XXX_hdr
   21:     {
   22:         u_char  field1;
   23:         u_short field2;
   24:         u_long  field3;
   25:     };
   26: 
   27:     2) Add a pblock definition to libnet-structures.h (appened to the list):
   28: 
   29:     #define LIBNET_PBLOCK_XXX_H            0xNUMBER 
   30: 
   31:     3) Then work from the following template for libnet_build_XXX.c:
   32: 
   33: #if (HAVE_CONFIG_H)
   34: #include "../include/config.h"
   35: #endif
   36: #include "../include/libnet.h"
   37: 
   38: 
   39: libnet_ptag_t
   40: libnet_build_XXX(u_char arg1, u_short arg2, u_long arg3, u_char *payload,
   41:             u_long payload_s, libnet_t *l, libnet_ptag_t ptag)
   42: {
   43:     /*
   44:      *  n is the size of the protocol unit.  This is usually the header size
   45:      *  plus the payload size.  This is also how many bytes are allocated on
   46:      *  the heap to hold this protocol unit.
   47:      */
   48:     u_long n;
   49: 
   50:     /*
   51:      *  h is used inside the pblock structure to let libnet know how big
   52:      *  much data to checksum.  This is different for different protocols.
   53:      *  The IPv4 checksum covers the IP header only, while TCP and UDP
   54:      *  checksums cover header and data.
   55:      */
   56:     u_short h;
   57: 
   58:     /*
   59:      *  p will be used to refer to the protocol block that will either be
   60:      *  allocated if the function's pt argument is 0, or located if ptag refers
   61:      *  to a previously created protocol unit.
   62:      */
   63:     libnet_pblock_t *p;
   64: 
   65:     /*
   66:      *  XXX_hdr is the header structure that will be overlaid onto the
   67:      *  allocated memory by way of a memcpy.
   68:      */
   69:     struct libnet_XXX_hdr XXX_hdr;
   70: 
   71:     /*
   72:      *  Here we sanity check to make sure we have a live l.
   73:      */
   74:     if (l == NULL)
   75:     { 
   76:         return (-1);
   77:     }
   78: 
   79:     n = LIBNET_XXX_H + payload_s;
   80:     h = 0;          /* no checksum by default */
   81: 
   82:     /*
   83:      *  Find the existing protocol block if a ptag is specified, or create
   84:      *  a new one.
   85:      */
   86:     p = libnet_pblock_probe(l, pt, n, LIBNET_PBLOCK_XXX_H);
   87:     if (p == NULL)
   88:     {
   89:         return (-1);
   90:     }
   91: 
   92:     /*
   93:      *  Build your packet here.  Be sure to call appropriate endian conversion
   94:      *  routines.
   95:      */
   96:     XXX_hdr.field1 = arg1;
   97:     XXX_hdr.field2 = htons(arg2);
   98:     XXX_hdr.field3 = htonl(arg3);
   99: 
  100:     /*
  101:      *  Appened the protocol unit to the list.
  102:      */
  103:     n = libnet_pblock_append(l, p, (u_char *)&XXX_hdr, LIBNET_XXX_H);
  104:     if (n == -1)
  105:     {
  106:         goto bad;
  107:     }
  108: 
  109:     /*
  110:      *  Sanity check the payload arguments.
  111:      */
  112:     if ((payload && !payload_s) || (!payload && payload_s))
  113:     {
  114:         sprintf(l->err_buf, "%s(): payload inconsistency\n", __FUNCTION__);
  115:         goto bad;
  116:     }
  117: 
  118:     /*
  119:      *  Append the payload to the list if it exists.
  120:      */
  121:     if (payload && payload_s)
  122:     {
  123:         n = libnet_pblock_append(l, p, payload, payload_s);
  124:         if (n == -1)
  125:         {
  126:             goto bad;
  127:         }
  128:     }
  129: 
  130:     /*
  131:      *  If this packet header has a checksum field, you'll add this
  132:      *  and you'll have to edit libnet_checksum.c to add it to the switch
  133:      *  table.  You might have to define the protocol number too.
  134:      */
  135:     if (sum == 0 && l->injection_type != LIBNET_RAW4)
  136:     {
  137:         /*
  138:          *  If checksum is zero, by default libnet will compute a checksum
  139:          *  for the user.  The programmer can override this by calling
  140:          *  libnet_toggle_checksum(l, ptag, 1);
  141:          */
  142:         libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
  143:     }
  144: 
  145:     /*
  146:      *  Update the protocol block's meta information and return the protocol
  147:      *  tag id of this pblock.  This tag will be used to locate the pblock
  148:      *  in order to modify the protocol header in subsequent calls.
  149:      */
  150:     return (pt ? pt : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_XXX_H));
  151: bad:
  152:     libnet_pblock_delete(l, p);
  153:     return (-1);
  154: 
  155: }
  156:     4) Add it to src/Makefile.am and then automake from the TLD.
  157:     5) Test the shit out of it.
  158:     6) Send it over to mike@infonexus.com.
  159: 
  160: 
  161: EOF

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