File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libnet / doc / PACKET_BUILDING
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 11:54:41 2013 UTC (11 years, 11 months ago) by misho
Branches: libnet, MAIN
CVS tags: v1_1_6p5, v1_1_6p4, v1_1_6p0, v1_1_6, HEAD
1.1.6

    1: ===============================================================================
    2:     $Id: PACKET_BUILDING,v 1.1.1.2 2013/07/22 11:54:41 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, STATIC HEADER SIZE
    9: 
   10: Adding a new packet building module to libnet is usually pretty simple. The
   11: following short document details how to add a packet builder to libnet for a
   12: protocol that has a static header size. We'll use the Sebek protocol as an
   13: example to walk through the process.
   14: 
   15: 1) Make sure you have a good reference for the protocol in question. Be it an
   16:    RFC or an official release doc from the author or vendor, you'll need
   17:    something comprehensive. For Sebek, the comprehensive reference is here:
   18:    http://project.honeynet.org.
   19: 
   20: 2) Figure out how big the header is and add it to the top of libnet-headers.h:
   21: 
   22: #define LIBNET_SEBEK_H          0x30    /* sebek header:          48 bytes */   
   23: 
   24: 3) Create the protocol header structure and add it to the end of
   25:    libnet-headers.h. Take care to use POSIX datatypes to define all of your
   26:    values. Structure naming conventions are more or less up to you. Since
   27:    they're never exported to the user, it's not a big deal, but try to keep
   28:    them short and descriptive. Convention is to add the symbolic constant 
   29:    #defines above the structure members they apply to.
   30: 
   31: /*
   32:  *  Sebek header
   33:  *  Static header size: 48 bytes
   34:  */
   35: struct libnet_sebek_hdr
   36: {
   37:     u_int32_t magic;                /* identify packets that should be hidden */
   38:     u_int16_t version;              /* protocol version, currently 1 */
   39: #define SEBEK_PROTO_VERSION 1
   40:     u_int16_t type;                 /* type of record */
   41: #define SEBEK_TYPE_READ     0       /* currently, only read is supported */
   42: #define SEBEK_TYPE_WRITE    1
   43:     u_int32_t counter;              /* PDU counter */
   44:     u_int32_t time_sec;             /* EPOCH timer */
   45:     u_int32_t time_usec;            /* residual microseconds */
   46:     u_int32_t pid;                  /* PID */
   47:     u_int32_t uid;                  /* UID */
   48:     u_int32_t fd;                   /* FD */
   49: #define SEBEK_CMD_LENGTH   12
   50:     u_int8_t cmd[SEBEK_CMD_LENGTH]; /* 12 first characters of the command */
   51:     u_int32_t length;               /* PDU length */
   52: };
   53: 
   54: 3) Append a pblock identifier to the end of the list in libnet-structures.h.
   55:    The ID number is not imporant as long as it is UNIQUE. As such, just find
   56:    the last entry, append the new entry after it, and increase the pblock ID
   57:    by one:
   58: 
   59: #define LIBNET_PBLOCK_SEBEK_H           0x3f    /* Sebek header */
   60: 
   61: 4) Create your new builder file in src/. Adhere to the "libnet_build_PROTOCOL.c"
   62:    convention. I recommend copying one of the existing builder modules and
   63:    modifying it as you go.
   64: 
   65: 
   66: 4a) 
   67: 
   68: #if (HAVE_CONFIG_H)
   69: #include "../include/config.h"
   70: #endif
   71: #if (!(_WIN32) || (__CYGWIN__)) 
   72: #include "../include/libnet.h"
   73: #else
   74: #include "../include/win32/libnet.h"
   75: #endif
   76: 
   77: libnet_ptag_t
   78: libnet_build_sebek(u_int32_t magic, u_int16_t version, u_int16_t type,
   79: u_int32_t counter, u_int32_t time_sec, u_int32_t time_usec, u_int32_t pid,
   80: u_int32_t uid, u_int32_t fd, u_int8_t cmd[SEBEK_CMD_LENGTH], u_int32_t length,
   81: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
   82: {
   83: 
   84: 
   85: libnet_ptag_t
   86: libnet_build_XXX(u_char arg1, u_short arg2, u_long arg3, u_char *payload,
   87:             u_long payload_s, libnet_t *l, libnet_ptag_t ptag)
   88: {
   89:     /*
   90:      *  n is the size of the protocol unit.  This is usually the header size
   91:      *  plus the payload size.  This is also how many bytes are allocated on
   92:      *  the heap to hold this protocol unit.
   93:      */
   94:     u_long n;
   95: 
   96:     /*
   97:      *  h is used inside the pblock structure to let libnet know how big
   98:      *  much data to checksum.  This is different for different protocols.
   99:      *  The IPv4 checksum covers the IP header only, while TCP and UDP
  100:      *  checksums cover header and data.
  101:      */
  102:     u_short h;
  103: 
  104:     /*
  105:      *  p will be used to refer to the protocol block that will either be
  106:      *  allocated if the function's pt argument is 0, or located if ptag refers
  107:      *  to a previously created protocol unit.
  108:      */
  109:     libnet_pblock_t *p;
  110: 
  111:     /*
  112:      *  XXX_hdr is the header structure that will be overlaid onto the
  113:      *  allocated memory by way of a memcpy.
  114:      */
  115:     struct libnet_XXX_hdr XXX_hdr;
  116: 
  117:     /*
  118:      *  Here we sanity check to make sure we have a live l.
  119:      */
  120:     if (l == NULL)
  121:     { 
  122:         return (-1);
  123:     }
  124: 
  125:     n = LIBNET_XXX_H + payload_s;
  126:     h = 0;          /* no checksum by default */
  127: 
  128:     /*
  129:      *  Find the existing protocol block if a ptag is specified, or create
  130:      *  a new one.
  131:      */
  132:     p = libnet_pblock_probe(l, pt, n, LIBNET_PBLOCK_XXX_H);
  133:     if (p == NULL)
  134:     {
  135:         return (-1);
  136:     }
  137: 
  138:     /*
  139:      *  Build your packet here.  Be sure to call appropriate endian conversion
  140:      *  routines.
  141:      */
  142:     XXX_hdr.field1 = arg1;
  143:     XXX_hdr.field2 = htons(arg2);
  144:     XXX_hdr.field3 = htonl(arg3);
  145: 
  146:     /*
  147:      *  Appened the protocol unit to the list.
  148:      */
  149:     n = libnet_pblock_append(l, p, (u_char *)&XXX_hdr, LIBNET_XXX_H);
  150:     if (n == -1)
  151:     {
  152:         goto bad;
  153:     }
  154: 
  155:     /*
  156:      *  Sanity check the payload arguments.
  157:      */
  158:     if ((payload && !payload_s) || (!payload && payload_s))
  159:     {
  160:         sprintf(l->err_buf, "%s(): payload inconsistency\n", __FUNCTION__);
  161:         goto bad;
  162:     }
  163: 
  164:     /*
  165:      *  Append the payload to the list if it exists.
  166:      */
  167:     if (payload && payload_s)
  168:     {
  169:         n = libnet_pblock_append(l, p, payload, payload_s);
  170:         if (n == -1)
  171:         {
  172:             goto bad;
  173:         }
  174:     }
  175: 
  176:     /*
  177:      *  If this packet header has a checksum field, you'll add this
  178:      *  and you'll have to edit libnet_checksum.c to add it to the switch
  179:      *  table.  You might have to define the protocol number too.
  180:      */
  181:     if (sum == 0 && l->injection_type != LIBNET_RAW4)
  182:     {
  183:         /*
  184:          *  If checksum is zero, by default libnet will compute a checksum
  185:          *  for the user.  The programmer can override this by calling
  186:          *  libnet_toggle_checksum(l, ptag, 1);
  187:          */
  188:         libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
  189:     }
  190: 
  191:     /*
  192:      *  Update the protocol block's meta information and return the protocol
  193:      *  tag id of this pblock.  This tag will be used to locate the pblock
  194:      *  in order to modify the protocol header in subsequent calls.
  195:      */
  196:     return (pt ? pt : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_XXX_H));
  197: bad:
  198:     libnet_pblock_delete(l, p);
  199:     return (-1);
  200: 
  201: }
  202:     4) Add it to src/Makefile.am and then automake from the TLD.
  203:     5) Test the shit out of it.
  204:     6) Send it over to mike@infonexus.com.
  205: 
  206: 
  207: EOF

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