Annotation of embedaddon/libnet/doc/PACKET_BUILDING, revision 1.1.1.2

1.1       misho       1: ===============================================================================
1.1.1.2 ! misho       2:     $Id: PACKET_BUILDING,v 1.3 2004/04/13 17:32:28 mike Exp $
1.1       misho       3:     LIBNET 1.1 (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
                      4:                                http://www.packetfactory.net/libnet
                      5: ===============================================================================
                      6: 
                      7: 
1.1.1.2 ! misho       8:     ADDING A NEW PACKET BUILDER, STATIC HEADER SIZE
1.1       misho       9: 
1.1.1.2 ! misho      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.
1.1       misho      64: 
                     65: 
1.1.1.2 ! misho      66: 4a) 
1.1       misho      67: 
                     68: #if (HAVE_CONFIG_H)
                     69: #include "../include/config.h"
                     70: #endif
1.1.1.2 ! misho      71: #if (!(_WIN32) || (__CYGWIN__)) 
1.1       misho      72: #include "../include/libnet.h"
1.1.1.2 ! misho      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: {
1.1       misho      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>