Blame doc/PACKET_BUILDING

Packit 03b34a
===============================================================================
Packit 03b34a
    $Id: PACKET_BUILDING,v 1.3 2004/04/13 17:32:28 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
    ADDING A NEW PACKET BUILDER, STATIC HEADER SIZE
Packit 03b34a
Packit 03b34a
Adding a new packet building module to libnet is usually pretty simple. The
Packit 03b34a
following short document details how to add a packet builder to libnet for a
Packit 03b34a
protocol that has a static header size. We'll use the Sebek protocol as an
Packit 03b34a
example to walk through the process.
Packit 03b34a
Packit 03b34a
1) Make sure you have a good reference for the protocol in question. Be it an
Packit 03b34a
   RFC or an official release doc from the author or vendor, you'll need
Packit 03b34a
   something comprehensive. For Sebek, the comprehensive reference is here:
Packit 03b34a
   http://project.honeynet.org.
Packit 03b34a
Packit 03b34a
2) Figure out how big the header is and add it to the top of libnet-headers.h:
Packit 03b34a
Packit 03b34a
#define LIBNET_SEBEK_H          0x30    /* sebek header:          48 bytes */   
Packit 03b34a
Packit 03b34a
3) Create the protocol header structure and add it to the end of
Packit 03b34a
   libnet-headers.h. Take care to use POSIX datatypes to define all of your
Packit 03b34a
   values. Structure naming conventions are more or less up to you. Since
Packit 03b34a
   they're never exported to the user, it's not a big deal, but try to keep
Packit 03b34a
   them short and descriptive. Convention is to add the symbolic constant 
Packit 03b34a
   #defines above the structure members they apply to.
Packit 03b34a
Packit 03b34a
/*
Packit 03b34a
 *  Sebek header
Packit 03b34a
 *  Static header size: 48 bytes
Packit 03b34a
 */
Packit 03b34a
struct libnet_sebek_hdr
Packit 03b34a
{
Packit 03b34a
    u_int32_t magic;                /* identify packets that should be hidden */
Packit 03b34a
    u_int16_t version;              /* protocol version, currently 1 */
Packit 03b34a
#define SEBEK_PROTO_VERSION 1
Packit 03b34a
    u_int16_t type;                 /* type of record */
Packit 03b34a
#define SEBEK_TYPE_READ     0       /* currently, only read is supported */
Packit 03b34a
#define SEBEK_TYPE_WRITE    1
Packit 03b34a
    u_int32_t counter;              /* PDU counter */
Packit 03b34a
    u_int32_t time_sec;             /* EPOCH timer */
Packit 03b34a
    u_int32_t time_usec;            /* residual microseconds */
Packit 03b34a
    u_int32_t pid;                  /* PID */
Packit 03b34a
    u_int32_t uid;                  /* UID */
Packit 03b34a
    u_int32_t fd;                   /* FD */
Packit 03b34a
#define SEBEK_CMD_LENGTH   12
Packit 03b34a
    u_int8_t cmd[SEBEK_CMD_LENGTH]; /* 12 first characters of the command */
Packit 03b34a
    u_int32_t length;               /* PDU length */
Packit 03b34a
};
Packit 03b34a
Packit 03b34a
3) Append a pblock identifier to the end of the list in libnet-structures.h.
Packit 03b34a
   The ID number is not imporant as long as it is UNIQUE. As such, just find
Packit 03b34a
   the last entry, append the new entry after it, and increase the pblock ID
Packit 03b34a
   by one:
Packit 03b34a
Packit 03b34a
#define LIBNET_PBLOCK_SEBEK_H           0x3f    /* Sebek header */
Packit 03b34a
Packit 03b34a
4) Create your new builder file in src/. Adhere to the "libnet_build_PROTOCOL.c"
Packit 03b34a
   convention. I recommend copying one of the existing builder modules and
Packit 03b34a
   modifying it as you go.
Packit 03b34a
Packit 03b34a
Packit 03b34a
4a) 
Packit 03b34a
Packit 03b34a
#if (HAVE_CONFIG_H)
Packit 03b34a
#include "../include/config.h"
Packit 03b34a
#endif
Packit 03b34a
#if (!(_WIN32) || (__CYGWIN__)) 
Packit 03b34a
#include "../include/libnet.h"
Packit 03b34a
#else
Packit 03b34a
#include "../include/win32/libnet.h"
Packit 03b34a
#endif
Packit 03b34a
Packit 03b34a
libnet_ptag_t
Packit 03b34a
libnet_build_sebek(u_int32_t magic, u_int16_t version, u_int16_t type,
Packit 03b34a
u_int32_t counter, u_int32_t time_sec, u_int32_t time_usec, u_int32_t pid,
Packit 03b34a
u_int32_t uid, u_int32_t fd, u_int8_t cmd[SEBEK_CMD_LENGTH], u_int32_t length,
Packit 03b34a
u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
Packit 03b34a
{
Packit 03b34a
Packit 03b34a
Packit 03b34a
libnet_ptag_t
Packit 03b34a
libnet_build_XXX(u_char arg1, u_short arg2, u_long arg3, u_char *payload,
Packit 03b34a
            u_long payload_s, libnet_t *l, libnet_ptag_t ptag)
Packit 03b34a
{
Packit 03b34a
    /*
Packit 03b34a
     *  n is the size of the protocol unit.  This is usually the header size
Packit 03b34a
     *  plus the payload size.  This is also how many bytes are allocated on
Packit 03b34a
     *  the heap to hold this protocol unit.
Packit 03b34a
     */
Packit 03b34a
    u_long n;
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  h is used inside the pblock structure to let libnet know how big
Packit 03b34a
     *  much data to checksum.  This is different for different protocols.
Packit 03b34a
     *  The IPv4 checksum covers the IP header only, while TCP and UDP
Packit 03b34a
     *  checksums cover header and data.
Packit 03b34a
     */
Packit 03b34a
    u_short h;
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  p will be used to refer to the protocol block that will either be
Packit 03b34a
     *  allocated if the function's pt argument is 0, or located if ptag refers
Packit 03b34a
     *  to a previously created protocol unit.
Packit 03b34a
     */
Packit 03b34a
    libnet_pblock_t *p;
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  XXX_hdr is the header structure that will be overlaid onto the
Packit 03b34a
     *  allocated memory by way of a memcpy.
Packit 03b34a
     */
Packit 03b34a
    struct libnet_XXX_hdr XXX_hdr;
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  Here we sanity check to make sure we have a live l.
Packit 03b34a
     */
Packit 03b34a
    if (l == NULL)
Packit 03b34a
    { 
Packit 03b34a
        return (-1);
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    n = LIBNET_XXX_H + payload_s;
Packit 03b34a
    h = 0;          /* no checksum by default */
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  Find the existing protocol block if a ptag is specified, or create
Packit 03b34a
     *  a new one.
Packit 03b34a
     */
Packit 03b34a
    p = libnet_pblock_probe(l, pt, n, LIBNET_PBLOCK_XXX_H);
Packit 03b34a
    if (p == NULL)
Packit 03b34a
    {
Packit 03b34a
        return (-1);
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  Build your packet here.  Be sure to call appropriate endian conversion
Packit 03b34a
     *  routines.
Packit 03b34a
     */
Packit 03b34a
    XXX_hdr.field1 = arg1;
Packit 03b34a
    XXX_hdr.field2 = htons(arg2);
Packit 03b34a
    XXX_hdr.field3 = htonl(arg3);
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  Appened the protocol unit to the list.
Packit 03b34a
     */
Packit 03b34a
    n = libnet_pblock_append(l, p, (u_char *)&XXX_hdr, LIBNET_XXX_H);
Packit 03b34a
    if (n == -1)
Packit 03b34a
    {
Packit 03b34a
        goto bad;
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  Sanity check the payload arguments.
Packit 03b34a
     */
Packit 03b34a
    if ((payload && !payload_s) || (!payload && payload_s))
Packit 03b34a
    {
Packit 03b34a
        sprintf(l->err_buf, "%s(): payload inconsistency\n", __FUNCTION__);
Packit 03b34a
        goto bad;
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  Append the payload to the list if it exists.
Packit 03b34a
     */
Packit 03b34a
    if (payload && payload_s)
Packit 03b34a
    {
Packit 03b34a
        n = libnet_pblock_append(l, p, payload, payload_s);
Packit 03b34a
        if (n == -1)
Packit 03b34a
        {
Packit 03b34a
            goto bad;
Packit 03b34a
        }
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  If this packet header has a checksum field, you'll add this
Packit 03b34a
     *  and you'll have to edit libnet_checksum.c to add it to the switch
Packit 03b34a
     *  table.  You might have to define the protocol number too.
Packit 03b34a
     */
Packit 03b34a
    if (sum == 0 && l->injection_type != LIBNET_RAW4)
Packit 03b34a
    {
Packit 03b34a
        /*
Packit 03b34a
         *  If checksum is zero, by default libnet will compute a checksum
Packit 03b34a
         *  for the user.  The programmer can override this by calling
Packit 03b34a
         *  libnet_toggle_checksum(l, ptag, 1);
Packit 03b34a
         */
Packit 03b34a
        libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
Packit 03b34a
    }
Packit 03b34a
Packit 03b34a
    /*
Packit 03b34a
     *  Update the protocol block's meta information and return the protocol
Packit 03b34a
     *  tag id of this pblock.  This tag will be used to locate the pblock
Packit 03b34a
     *  in order to modify the protocol header in subsequent calls.
Packit 03b34a
     */
Packit 03b34a
    return (pt ? pt : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_XXX_H));
Packit 03b34a
bad:
Packit 03b34a
    libnet_pblock_delete(l, p);
Packit 03b34a
    return (-1);
Packit 03b34a
Packit 03b34a
}
Packit 03b34a
    4) Add it to src/Makefile.am and then automake from the TLD.
Packit 03b34a
    5) Test the shit out of it.
Packit 03b34a
    6) Send it over to mike@infonexus.com.
Packit 03b34a
Packit 03b34a
Packit 03b34a
EOF