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