1 /* dummy.c - example sendip module
2 * Author: Mike Ricketts <mike@earth.li>
3 * ChangeLog since 2.0 release:
4 * 02/12/2001: added num_opts, get_opts and get_optchar functions
5 * 02/12/2001: added more helpful comments
6 */
7
8 /* To write a new sendip module:
9 * * mail mike@earth.li to check that nobody else is already working on the
10 * same thing.
11 * * copy dummy.c and dummy.h
12 * * replace dummy with the name of your module throughout
13 * * In <your_module>.h:
14 * - fill in the struct foo_header with all the header fields in your
15 * module's packet. If the packet is a variable length, only put the
16 * common bits here and use additional structs for other bits, if needed.
17 * Be very careful about introducing byteorder dependencies. See ntp.h
18 * for a simple case of how to do it. In general, things smaller than
19 * 16 bits are problematic, use the __BYTE_ORDER macro and test against
20 * __LITTLE_ENDIAN, __BIG_ENDIAN. Always have a #else catchall with a
21 * #error in, just in case.
22 * Every field should be a u_int*_t or an int*_t to avoid things being
23 * differnt lengths from you expect. Use these rather than equivalent
24 * ones as these will exist everywhere that sendip compiles.
25 * - create a list of #defines FOO_MOD_*, one for each header field that
26 * may be modified. The first should have value 1, the rest should be
27 * 1<<x for increasing values of x.
28 * - fill in the foo_opts array for all the options your module supports.
29 * Each entry has the format:
30 * {opt_string,arg,description,default}
31 * opt_string is the option that is used to set it, EXCLUDING the -x that
32 * tells sendip which module. arg is 0 (for no value) or 1 if the option
33 * takes a value (almost always). description should be a short
34 * explanation of what the option does, and default should be its default
35 * value (as a string, can be NULL if there is no default).
36 * - remove the #error line at the top
37 * * In <your_module>.c:
38 * - remove this essay (you can still read it in dummy.c!)
39 * - change the top comment in the obvious way
40 * - find an option character not used elsewhere and replace opt_char with
41 * that. You can see what is used by doing
42 * grep '^const char opt_char' *.c
43 * in the sendip source directory.
44 * - in the do_opt function, fill in code for all the options you defined in
45 * the header file. Typically, the code will look a lot like:
46 * case 'option':
47 * header->thing = htons((u_int16_t)strtoul(arg, (char **)NULL, 0));
48 * pack->modified |= FOO_MOD_THING;
49 * break;
50 * If some of your options change the length of the packet, you might want
51 * to take a look in ipv4.c or tcp.c - specifically where they add IPV4 or
52 * TCP options.
53 * Make sure you use htons and htonl everywhere you need to to avoid
54 * byteorder problems.
55 * -opt contains the option string, including the starting opt_char
56 * -arg contains any argument given
57 * -pack contains our headers
58 * - in the finalize function, fill in anything that needs to be computed
59 * after all the optoins are processed. This function MUST NOT change
60 * the length or location of the headers in memory, else bad things will
61 * happen. Typical things that go in here are filling in the length
62 * field of the header if it hasn't been overriden, computing checksums,
63 * etc. You may also which to check that your packet is enclosed in a
64 * sensible carrier. tcp.c does all of the things.
65 * -hdrs is build by taking the opt_char for each packet in turn from the
66 * outside in, up to but not including this packet
67 * -headers is an array of all the enclosing headers in the same order
68 * -data contains the data inside this set of headers. This may include
69 * headers of underlying protocols, that will already have been
70 * finalized. DO NOT MODIFY IT.
71 * -pack contains our headers.
72 * - You might, possibly, find the following functions useful. They are
73 * automatically available to all modules:
74 * -int compact_string(char *string);
75 * For strings starting 0x or 0X, converts each pair of bytes thereafter
76 * to a single byte of that hex value. For other strings starting 0,
77 * converts sets of 3 bytes to a single byte of that octal value. For
78 * all other strings, does nothing. Returns the length of the final
79 * string. This is recomended when parsing arbitrary data (like the -d
80 * option of sendip, -tonum for arbitrary TCP options)
81 * -u_int16_t csum(u_int16_t *data, int len)
82 * returns the standard internet checksum of the packet
83 * - If something doesn't work as expected, or you can't figure out how to
84 * do sometihng, mail mike@earth.li and ask.
85 * * In the Makefile add <your_module>.so to the PROTOS line
86 * * Test it
87 * * Mail it to mike@earth.li, either as a patch or just send the .c and .h
88 * files you created
89 */
90
91 #include <stdlib.h>
92 #include <sys/types.h>
93 #include "sendip_module.h"
94 #include "dummy.h"
95
96 /* Character that identifies our options
97 */
98 const char opt_char='dummy';
99
initialize(void)100 sendip_data *initialize(void) {
101 sendip_data *ret = malloc(sizeof(sendip_data));
102 dummy_header *dummy = malloc(sizeof(dummy_header));
103 memset(dummy,0,sizeof(dummy_header));
104 ret->alloc_len = sizeof(dummy_header);
105 ret->data = dummy;
106 ret->modified=0;
107 return ret;
108 }
109
do_opt(char * opt,char * arg,sendip_data * pack)110 bool do_opt(char *opt, char *arg, sendip_data *pack) {
111 dummy_header *dummy = (dummy_header *)pack->data;
112 switch(opt[1]) {
113 //...
114 }
115 return TRUE;
116
117 }
118
finalize(char * hdrs,sendip_data * headers[],sendip_data * data,sendip_data * pack)119 bool finalize(char *hdrs, sendip_data *headers[], sendip_data *data,
120 sendip_data *pack) {
121 //...
122 return TRUE;
123 }
124
num_opts()125 int num_opts() {
126 return sizeof(dummy_opts)/sizeof(sendip_option);
127 }
get_opts()128 sendip_option *get_opts() {
129 return dummy_opts;
130 }
get_optchar()131 char get_optchar() {
132 return opt_char;
133 }
134