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>