plan to cleanup the fd generation code
[trinity.git] / params.c
blob67f59f838207df93ec66648f3f64f117429aaf33
1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <getopt.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
9 #include "child.h"
10 #include "log.h"
11 #include "net.h"
12 #include "params.h"
13 #include "protocols.h"
14 #include "random.h"
15 #include "syscall.h"
16 #include "tables.h"
17 #include "taint.h"
18 #include "trinity.h" // progname
20 bool debug = FALSE;
22 bool do_specific_syscall = FALSE;
23 bool do_exclude_syscall = FALSE;
25 bool do_32_arch = TRUE;
26 bool do_64_arch = TRUE;
28 unsigned int specific_proto = 0;
29 unsigned int user_specified_children = 0;
31 bool do_specific_proto = FALSE;
32 bool no_protos[TRINITY_PF_MAX];
34 bool dopause = FALSE;
35 bool show_syscall_list = FALSE;
36 bool show_ioctl_list = FALSE;
37 unsigned char quiet_level = 0;
38 bool verbose = FALSE;
39 bool monochrome = FALSE;
40 bool dangerous = FALSE;
41 bool dropprivs = FALSE;
42 bool logging = TRUE;
43 bool do_syslog = FALSE;
44 bool random_selection = FALSE;
45 unsigned int random_selection_num;
46 bool no_files = FALSE;
48 bool user_set_seed = FALSE;
50 unsigned char desired_group = GROUP_NONE;
52 char *specific_proto_optarg = NULL;
54 char *victim_path = NULL;
56 unsigned int kernel_taint_mask = 0xFFFFFFFF;
57 bool kernel_taint_param_occured = FALSE;
59 static void usage(void)
61 outputerr("%s\n", progname);
62 outputerr(" --arch, -a: selects syscalls for the specified architecture (32 or 64). Both by default.\n");
63 outputerr(" --children,-C: specify number of child processes\n");
64 outputerr(" --debug,-D: enable debug\n");
65 outputerr(" --dropprivs, -X: if run as root, switch to nobody [EXPERIMENTAL]\n");
66 outputerr(" --exclude,-x: don't call a specific syscall\n");
67 outputerr(" --group,-g: only run syscalls from a certain group (So far just 'vm').\n");
68 outputerr(" --ioctls,-I: list all ioctls.\n");
69 outputerr(" --kernel_taint, -T: controls which kernel taint flags should be considered, for more details refer to README file. \n");
70 outputerr(" --list,-L: list all syscalls known on this architecture.\n");
71 outputerr(" --logging,-l: (off=disable logging).\n");
72 outputerr(" --monochrome,-m: don't output ANSI codes\n");
73 outputerr(" --no_files,-n: Only pass sockets as fd's, not files\n");
74 outputerr(" --proto,-P: specify specific network protocol for sockets.\n");
75 outputerr(" --no_proto,-E: specify network protocols to be excluded from testing.\n");
76 outputerr(" --quiet,-q: less output.\n");
77 outputerr(" --random,-r#: pick N syscalls at random and just fuzz those\n");
78 outputerr(" --syslog,-S: log important info to syslog. (useful if syslog is remote)\n");
79 outputerr(" --verbose,-v: increase output verbosity.\n");
80 outputerr(" --victims,-V: path to victim files.\n");
81 outputerr("\n");
82 outputerr(" -c#,@: target specific syscall (takes syscall name as parameter and optionally 32 or 64 as bit-width. Default:both).\n");
83 outputerr(" -N#: do # syscalls then exit.\n");
84 outputerr(" -p: pause after syscall.\n");
85 outputerr(" -s#: use # as random seed.\n");
86 exit(EXIT_SUCCESS);
89 static const char paramstr[] = "a:c:C:dDg:hIl:LN:mnP:E:pqr:s:T:SV:vx:X";
91 static const struct option longopts[] = {
92 { "children", required_argument, NULL, 'C' },
93 { "dangerous", no_argument, NULL, 'd' },
94 { "dropprivs", no_argument, NULL, 'X'},
95 { "debug", no_argument, NULL, 'D' },
96 { "exclude", required_argument, NULL, 'x' },
97 { "group", required_argument, NULL, 'g' },
98 { "kernel_taint", required_argument, NULL, 'T' },
99 { "help", no_argument, NULL, 'h' },
100 { "list", no_argument, NULL, 'L' },
101 { "ioctls", no_argument, NULL, 'I' },
102 { "logging", required_argument, NULL, 'l' },
103 { "monochrome", no_argument, NULL, 'm' },
104 { "no_files", no_argument, NULL, 'n' },
105 { "proto", required_argument, NULL, 'P' },
106 { "no_proto", required_argument, NULL, 'E' },
107 { "random", required_argument, NULL, 'r' },
108 { "quiet", no_argument, NULL, 'q' },
109 { "syslog", no_argument, NULL, 'S' },
110 { "victims", required_argument, NULL, 'V' },
111 { "verbose", no_argument, NULL, 'v' },
112 { "arch", required_argument, NULL, 'a' },
113 { NULL, 0, NULL, 0 } };
115 void parse_args(int argc, char *argv[])
117 int opt;
119 while ((opt = getopt_long(argc, argv, paramstr, longopts, NULL)) != -1) {
120 switch (opt) {
121 default:
122 if (opt == '?')
123 exit(EXIT_FAILURE);
124 else
125 outputstd("opt:%c\n", opt);
126 return;
128 case '\0':
129 return;
131 case 'c':
132 /* syscalls are all disabled at this point. enable the syscall we care about. */
133 do_specific_syscall = TRUE;
134 toggle_syscall(optarg, TRUE);
135 break;
137 case 'a':
138 /* One of the architectures selected*/
139 do_32_arch = FALSE;
140 do_64_arch = FALSE;
141 if (strcmp(optarg, "64") == 0) {
142 do_32_arch = FALSE;
143 do_64_arch = TRUE;
144 } else if (strcmp(optarg, "32") == 0) {
145 do_32_arch = TRUE;
146 do_64_arch = FALSE;
147 } else {
148 outputstd("can't parse %s\n", optarg);
149 exit(EXIT_FAILURE);
151 break;
153 case 'C':
154 user_specified_children = strtoll(optarg, NULL, 10);
155 max_children = user_specified_children;
157 if (max_children == 0) {
158 outputerr("zero children ? WAT?\n");
159 exit(EXIT_FAILURE);
161 break;
163 case 'd':
164 dangerous = TRUE;
165 break;
167 case 'D':
168 debug = TRUE;
169 break;
171 case 'g':
172 if (!strcmp(optarg, "vm"))
173 desired_group = GROUP_VM;
174 if (!strcmp(optarg, "vfs"))
175 desired_group = GROUP_VFS;
176 break;
178 /* Show help */
179 case 'h':
180 usage();
181 exit(EXIT_SUCCESS);
183 case 'I':
184 show_ioctl_list = TRUE;
185 break;
187 case 'l':
188 if (!strcmp(optarg, "off"))
189 logging = FALSE;
190 break;
192 case 'L':
193 show_syscall_list = TRUE;
194 break;
196 case 'm':
197 monochrome = TRUE;
198 break;
200 case 'n':
201 no_files = TRUE;
202 break;
204 /* Set number of syscalls to do */
205 case 'N':
206 syscalls_todo = strtoll(optarg, NULL, 10);
207 break;
209 /* Pause after each syscall */
210 case 'p':
211 dopause = TRUE;
212 break;
214 case 'P':
215 do_specific_proto = TRUE;
216 specific_proto = strtol(optarg, NULL, 10);
217 specific_proto_optarg = optarg;
218 break;
220 case 'E':
221 parse_exclude_protos(optarg);
222 break;
224 case 'q':
225 quiet_level++;
226 break;
228 case 'r':
229 if (do_exclude_syscall == TRUE) {
230 outputerr("-r needs to be before any -x options.\n");
231 exit(EXIT_FAILURE);
233 random_selection = TRUE;
234 random_selection_num = strtol(optarg, NULL, 10);
235 break;
237 /* Set seed */
238 case 's':
239 seed = strtol(optarg, NULL, 10);
240 user_set_seed = TRUE;
241 break;
244 case 'S':
245 do_syslog = TRUE;
246 break;
248 case 'T':
249 //Load mask for kernel taint flags.
250 process_taint_arg(optarg);
251 if (kernel_taint_mask != 0xFFFFFFFF)
252 outputstd("Custom kernel taint mask has been specified: 0x%08x (%d).\n",
253 kernel_taint_mask, kernel_taint_mask);
254 break;
256 case 'v':
257 verbose = TRUE;
258 break;
260 case 'V':
261 if (victim_path == NULL) {
262 victim_path = strdup(optarg);
263 break;
264 } else {
265 outputstd("Sorry, only one victim path right now.\n");
266 exit(EXIT_FAILURE);
268 //FIXME: Later, allow for multiple victim files
269 break;
271 case 'x':
272 do_exclude_syscall = TRUE;
273 toggle_syscall(optarg, FALSE);
274 break;
276 case 'X':
277 dropprivs = TRUE;
278 break;
281 if (quiet_level > MAX_LOGLEVEL)
282 quiet_level = MAX_LOGLEVEL;
284 quiet_level = MAX_LOGLEVEL - quiet_level;
286 outputstd("Done parsing arguments.\n");