File: README.modules

package info (click to toggle)
t50 5.8.7c-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 808 kB
  • sloc: ansic: 5,721; makefile: 111; sh: 27
file content (184 lines) | stat: -rw-r--r-- 13,474 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
How to create a new module for T50

Suppose you want to add a new protocol for packet injection on T50. Let's say
you want to add "Stream Control Transport Protocol" (SCTP). 

For this example I choose this protocol because it's defined in <linux/in.h>
header as IPPROTO_SCTP. You can code any protocol you want. But if your protocol
description (IPPROTO_xxx) isn't available on standard header files, you *MUST*
create your own definition on 'src/include/defines.h' file. The IPPROTO_T50
definition, for instance, is defined there.

Adding a module is a 5 step process:

** STEP 1:

The first step is to create a module that re-allocate, fills the packet buffer
and returns the packet buffer size to the caller. All module routines *MUST*
follow the signature defined in "typedefs.h":

┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ typedef void (*module_func_ptr_t)(const struct config_options * const __restrict__, size_t *); │
└────────────────────────────────────────────────────────────────────────────────────────────────┘

Your module *MUST* be created in src/modules/ directory as 'sctp.c'. You
*SHOULD* code something like this:

┌──────────────────────────────────────────────────────────────────────────────┐
│ #include <common.h>  /* Include all t50 definitions and prototypes. */       │
│                                                                              │
│ static void fill_sctp(void *buffer);                                         │
│ static size_t get_sctp_buffer_size(void);                                    │
│                                                                              │
│ /* This is the module! */                                                    │
│ void sctp(const struct config_options * const __restrict__ co, size_t *size) │
│ {                                                                            │
│   /* Working pointers to the buffer */                                       │
│   struct iphdr *ip;                                                          │
│                                                                              │
│   /* Get the packet size */                                                  │
│   *size = sizeof(struct iphdr) + get_sctp_buffer_size();                     │
│                                                                              │
│   /* Tries to reallocate space for the packet buffer, if necessary. */       │
│   alloc_packet(*size);                                                       │
│                                                                              │
│   /* Fill IP header */                                                       │
│   ip = ip_header(packet, *size,                                              │
│                                                                              │
│   fill_sctp(packet + sizeof(struct iphdr));                                  │
│ }                                                                            │
│                                                                              │
│ /* This will fill the buffer part of sctp protocol. */                       │
│ static void fill_sctp(void *buffer, size_t size) { ... }                     │
│                                                                              │
│ /* This is only an example! */                                               │
│ #define SCTP_SIZE 524                                                        │
│ static size_t get_sctp_buffer_size(void) { return SCTP_SIZE; }               │
└──────────────────────────────────────────────────────────────────────────────┘

Notice that "packet" is a global pointer to the packet buffer used by all
modules. It is necessary to reallocate the buffer for every module, since the
previous module who use it could leave a very small buffer behind.

Any protocol specific structures, types *SHOULD* be defined in a separated
header file 'sctp.h' in 'src/include/protocol/' directory and this header *MUST*
be added to '/src/include/common.h' file. 

The prototype of the module function *MUST* be added to 'src/include/modules.h'
file:

┌───────────────────────────────────────────────────────────────────────────────┐
│ extern void sctp(const struct config_options * const __restrict__, size_t *); │
└───────────────────────────────────────────────────────────────────────────────┘

Take a look at the actual modules. They are a little more complicated than this,
but essentially, that's all they do.

** STEP 2:

Create an entry on 'src/modules.c'. You *MUST* add a line like this before
END_MODULES_TABLE declaration: 

┌────────────────────────────────────────────────────────────────────────────────┐
│   MODULE_ENTRY(IPPROTO_SCTP, "SCTP","Stream Control Transport Protocol", sctp) │
│ END_MODULES_TABLE                                                              │
└────────────────────────────────────────────────────────────────────────────────┘

This way T50 now knows how to fill the packet for your protocol.

** STEP 3:

Change config_options structure on 'src/config.c' and 'src/include/config.h'.
Let's say that SCTP needs only one item called 'tag' (a 32 bits value) that
could be a random value. You can add a new structure on config_options:

┌───────────────────────────────────────────────────────────────────────────┐
│ struct {                                                                  │
│   uint32_t tag;                                                           │
│ } sctp;                                                                   │
└───────────────────────────────────────────────────────────────────────────┘

OBS: The "random" part depends on the module. The macro __RND(), defined in
'src/include/defines.h' will return an random value if its parameter is 0. You
acn use this on your function to garantee an random value if this 'tag' is
informed as 0 or not informed at all in the command line.

Now, add an OPTION_SCTP_TAG in the enumeration at the beggining of config.h file.

Add a default value to config_options 'co' variable at config.c, if you need
something different from 0.

Add an entry called 'sctp-tag' on long_opt array to allow you to change this
value through the command line:

┌───────────────────────────────────────────────────────────────────────────┐
│ { "sctp-tag",  required_argument, NULL, OPTION_SCTP_TAG },                │
└───────────────────────────────────────────────────────────────────────────┘

And, finally, change getConfigOptions() function, adding a 'case' inside the
'switch(cli_opts)' block, like this:

┌───────────────────────────────────────────────────────────────────────────┐
│ case OPTION_SCTP_TAG: co.sctp.tag = atoi(optarg): break;                  │
└───────────────────────────────────────────────────────────────────────────┘

** STEP 4

Create a routine showing the usage for SCTP protocol options and put it on
sctp_help.c at 'src/help/' directory:

┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│ void sctp_help(void)                                                                            │
│ {                                                                                               │
│   puts("SCTP Options:\n"                                                                        │
│        "    --sctp-tag NUM               SCTP tag number                  (default RANDOM)\n"); │
│ }                                                                                               │
└─────────────────────────────────────────────────────────────────────────────────────────────────┘

To keep the standard, the first line starts with a description of the protocol
followed by "Options:". The following lines are formated as (printf style):

  "    --%-23s %-32s (default: %s)\n"  

Where the first string (max 23 chars) is the option. The second string (32 chars
max) is a small description and the last string is a numeric value or "RANDOM",
depending of what you did in config_options 'co' and your module.

After creating the sctp_help() functiom, put a call on the usage routine at 'src/usage.c':

┌───────────────────────────────────────────────────────────────────────────────┐
│ ...                                                                           │
│ rsvp_help();                                                                  │
│ ipsec_help();                                                                 │
│ eigrp_help();                                                                 │
│ ospf_help();                                                                  │
│ sctp_help();    /* Added sctp help */                                         │
└───────────────────────────────────────────────────────────────────────────────┘

** STEP 5 (FINAL)

Modify the Makefile adding the object filename (sctp.o) file location on OBJS var:

┌────────────────────────────────────────────────────────────────────────────────┐
│ ...                                                                            │
│ $(OBJ_DIR)/modules/igmpv1.o \                                                  │
│ $(OBJ_DIR)/modules/icmp.o \                                                    │
│ $(OBJ_DIR)/modules/sctp.o \                           <-- here!                │
│ $(OBJ_DIR)/common.o \                                                          │
│ ...                                                                            │
└────────────────────────────────────────────────────────────────────────────────┘

And test everything trying to compile the project:

  $ make

Don't forget to compile in DEBUG mode and test everything with your favorite
debugger:

  $ DEBUG=1 make
  $ sudo gdb release/t50

Good luck!

Frederico Lamberti Pissarra
April 3rd, 2014