"Fossies" - the Fresh Open Source Software Archive 
Member "ettercap-0.8.3.1/utils/etterfilter/ef_encode.c" (1 Aug 2020, 14814 Bytes) of package /linux/privat/ettercap-0.8.3.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "ef_encode.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
0.8.3_vs_0.8.3.1.
1 /*
2 etterfilter -- the actual compiler
3
4 Copyright (C) ALoR & NaGA
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 */
21
22 #include <ef.h>
23 #include <ef_functions.h>
24 #include <ec_filter.h>
25
26 #include <ctype.h>
27
28 #include <regex.h>
29 #ifdef HAVE_PCRE
30 #include <pcre.h>
31 #endif
32
33 /* protos */
34
35 static char ** decode_args(char *args, int *nargs);
36 static char * strsep_quotes(char **stringp, const char delim);
37
38 /*******************************************/
39
40 /*
41 * search an offset and fill the filter_op structure
42 * return E_SUCCESS on error.
43 */
44 int encode_offset(char *string, struct filter_op *fop)
45 {
46 char *str, *p, *q, *tok;
47 int ret;
48
49 memset(fop, 0, sizeof(struct filter_op));
50
51 /* make the modifications on a copy */
52 str = strdup(string);
53
54 /*
55 * the offset contains at least one '.'
56 * we are sure because the syntax parser
57 * will not have passed it here if it is not
58 * in the right form.
59 */
60 p = ec_strtok(str, ".", &tok);
61 q = ec_strtok(NULL, ".", &tok);
62
63 /*
64 * the assumption above is not always true, e.g.:
65 * log(DATA,d "x.log");
66 * results in q == NULL.
67 */
68 if (q == NULL)
69 return -E_NOTFOUND;
70
71 /* the the virtual pointer from the table */
72 ret = get_virtualpointer(p, q, &fop->op.test.level, &fop->op.test.offset, &fop->op.test.size);
73
74 SAFE_FREE(str);
75
76 return ret;
77 }
78
79 /*
80 * assing the value of the const to the fop.value
81 *
82 * all the value are integer32 and are saved in host order
83 */
84 int encode_const(char *string, struct filter_op *fop)
85 {
86 char *p;
87
88 memset(fop, 0, sizeof(struct filter_op));
89
90 /* it is an hexadecimal value */
91 if (!strncmp(string, "0x", 2) && isxdigit((int)string[2])) {
92 fop->op.test.value = strtoul(string, NULL, 16);
93 return E_SUCCESS;
94
95 /* it is an integer value */
96 } else if (isdigit((int)string[0])) {
97 fop->op.test.value = strtoul(string, NULL, 10);
98 return E_SUCCESS;
99
100 /* it is an ip address */
101 } else if (string[0] == '\'' && string[strlen(string) - 1] == '\'') {
102 struct ip_addr ipaddr;
103
104 /* remove the single quote */
105 p = strchr(string + 1, '\'');
106 *p = '\0';
107
108 if (ip_addr_pton(string + 1, &ipaddr) == E_SUCCESS) {
109 switch (ntohs(ipaddr.addr_type)) {
110 case AF_INET:
111 /* 4-bytes - handle as a integer */
112 fop->op.test.value = ntohl(ipaddr.addr32[0]);
113 break;
114 case AF_INET6:
115 /* 16-bytes - handle as a byte pointer */
116 ip_addr_cpy((u_char*)&fop->op.test.ipaddr, &ipaddr);
117 break;
118 default:
119 return -E_FATAL;
120 }
121 }
122 else {
123 return -E_FATAL;
124 }
125
126 return E_SUCCESS;
127
128 /* it is a string */
129 } else if (string[0] == '\"' && string[strlen(string) - 1] == '\"') {
130
131 /* remove the quotes */
132 p = strchr(string + 1, '\"');
133 *p = '\0';
134
135 /* copy the string */
136 fop->op.test.string = (u_char*)strdup(string + 1);
137
138 /* escape it in the structure */
139 fop->op.test.slen = strescape((char*)fop->op.test.string,
140 (char*)fop->op.test.string, strlen(fop->op.test.string)+1);
141
142 return E_SUCCESS;
143
144 /* it is a constant */
145 } else if (isalpha((int)string[0])) {
146 return get_constant(string, &fop->op.test.value);
147 }
148
149 /* anything else is an error */
150 return -E_NOTFOUND;
151 }
152
153
154 /*
155 * parse a function and its arguments and fill the structure
156 */
157 int encode_function(char *string, struct filter_op *fop)
158 {
159 char *str = strdup(string);
160 int ret = -E_NOTFOUND;
161 char *name, *args;
162 int nargs = 0, i;
163 char **dec_args = NULL;
164 char *tok;
165
166 memset(fop, 0, sizeof(struct filter_op));
167
168 /* get the name of the function */
169 name = ec_strtok(string, "(", &tok);
170 /* get all the args */
171 args = name + strlen(name) + 1;
172
173 /* analyze the arguments */
174 dec_args = decode_args(args, &nargs);
175
176 /* this fop is a function */
177 fop->opcode = FOP_FUNC;
178
179 /* check if it is a known function */
180 if (!strcmp(name, "search")) {
181 if (nargs == 2) {
182 /* get the level (DATA or DECODED) */
183 if (encode_offset(dec_args[0], fop) == E_SUCCESS) {
184 /* encode offset wipe the fop !! */
185 fop->opcode = FOP_FUNC;
186 fop->op.func.op = FFUNC_SEARCH;
187 fop->op.func.string = (u_char*)strdup(dec_args[1]);
188 fop->op.func.slen = strescape((char*)fop->op.func.string,
189 (char*)fop->op.func.string, strlen(fop->op.func.string)+1);
190 ret = E_SUCCESS;
191 } else
192 SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
193 } else
194 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
195 } else if (!strcmp(name, "regex")) {
196 if (nargs == 2) {
197 int err;
198 regex_t regex;
199 char errbuf[100];
200
201 /* get the level (DATA or DECODED) */
202 if (encode_offset(dec_args[0], fop) == E_SUCCESS) {
203 /* encode offset wipe the fop !! */
204 fop->opcode = FOP_FUNC;
205 fop->op.func.op = FFUNC_REGEX;
206 fop->op.func.string = (u_char*)strdup(dec_args[1]);
207 fop->op.func.slen = strescape((char*)fop->op.func.string,
208 (char*)fop->op.func.string, strlen(fop->op.func.string)+1);
209 ret = E_SUCCESS;
210 } else
211 SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
212
213 /* check if the regex is valid */
214 err = regcomp(®ex, (const char*)fop->op.func.string, REG_EXTENDED | REG_NOSUB | REG_ICASE );
215 if (err) {
216 regerror(err, ®ex, errbuf, sizeof(errbuf));
217 SCRIPT_ERROR("%s", errbuf);
218 }
219
220 regfree(®ex);
221
222 } else
223 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
224 } else if (!strcmp(name, "pcre_regex")) {
225 #ifndef HAVE_PCRE
226 WARNING("The script contains pcre_regex, but you don't have support for it.");
227 #else
228 pcre *pregex;
229 const char *errbuf = NULL;
230 int erroff;
231
232 if (nargs == 2) {
233
234 /* get the level (DATA or DECODED) */
235 if (encode_offset(dec_args[0], fop) == E_SUCCESS) {
236 /* encode offset wipe the fop !! */
237 fop->opcode = FOP_FUNC;
238 fop->op.func.op = FFUNC_PCRE;
239 fop->op.func.string = strdup(dec_args[1]);
240 fop->op.func.slen = strlen(fop->op.func.string);
241 ret = E_SUCCESS;
242 } else
243 SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
244
245 /* check if the pcre is valid */
246 pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL );
247 if (pregex == NULL)
248 SCRIPT_ERROR("%s\n", errbuf);
249
250 pcre_free(pregex);
251 } else if (nargs == 3) {
252
253 fop->opcode = FOP_FUNC;
254 fop->op.func.op = FFUNC_PCRE;
255 /* substitution always at layer DATA */
256 fop->op.func.level = 5;
257 fop->op.func.string = strdup(dec_args[1]);
258 fop->op.func.slen = strlen(fop->op.func.string);
259 fop->op.func.replace = strdup(dec_args[2]);
260 fop->op.func.rlen = strlen(fop->op.func.replace);
261 ret = E_SUCCESS;
262
263 /* check if the pcre is valid */
264 pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL );
265 if (pregex == NULL)
266 SCRIPT_ERROR("%s\n", errbuf);
267
268 pcre_free(pregex);
269 } else
270 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
271 #endif
272 } else if (!strcmp(name, "replace")) {
273 if (nargs == 2) {
274 fop->op.func.op = FFUNC_REPLACE;
275 /* replace always operate at DATA level */
276 fop->op.func.level = 5;
277 fop->op.func.string = (u_char*)strdup(dec_args[0]);
278 fop->op.func.slen = strescape((char*)fop->op.func.string,
279 (char*)fop->op.func.string, strlen(fop->op.func.string)+1);
280 fop->op.func.replace = (u_char*)strdup(dec_args[1]);
281 fop->op.func.rlen = strescape((char*)fop->op.func.replace,
282 (char*)fop->op.func.replace, strlen(fop->op.func.replace)+1);
283 ret = E_SUCCESS;
284 } else
285 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
286 } else if (!strcmp(name, "inject")) {
287 if (nargs == 1) {
288 fop->op.func.op = FFUNC_INJECT;
289 /* inject always operate at DATA level */
290 fop->op.func.level = 5;
291 fop->op.func.string = (u_char*)strdup(dec_args[0]);
292 fop->op.func.slen = strlen((const char*)fop->op.func.string);
293 ret = E_SUCCESS;
294 } else
295 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
296 } else if (!strcmp(name, "execinject")) {
297 if (nargs == 1) {
298 fop->op.func.op = FFUNC_EXECINJECT;
299 /* execinject always operate at DATA level */
300 fop->op.func.level = 5;
301 fop->op.func.string = (u_char*)strdup(dec_args[0]);
302 fop->op.func.slen = strlen((const char*)fop->op.func.string);
303 ret = E_SUCCESS;
304 } else
305 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
306 } else if (!strcmp(name, "execreplace")) {
307 if (nargs == 1) {
308 fop->op.func.op = FFUNC_EXECREPLACE;
309 /* execreplace always operate at DATA level */
310 fop->op.func.level = 5;
311 fop->op.func.string = (u_char*)strdup(dec_args[0]);
312 fop->op.func.slen = strlen((const char*)fop->op.func.string);
313 ret = E_SUCCESS;
314 } else
315 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
316 } else if (!strcmp(name, "log")) {
317 if (nargs == 2) {
318 /* get the level (DATA or DECODED) */
319 if (encode_offset(dec_args[0], fop) == E_SUCCESS) {
320 /* encode offset wipe the fop !! */
321 fop->opcode = FOP_FUNC;
322 fop->op.func.op = FFUNC_LOG;
323 fop->op.func.string = (u_char*)strdup(dec_args[1]);
324 fop->op.func.slen = strlen((const char*)fop->op.func.string);
325 ret = E_SUCCESS;
326 } else
327 SCRIPT_ERROR("Unknown offset %s ", dec_args[0]);
328 } else
329 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
330 } else if (!strcmp(name, "drop")) {
331 if (nargs == 0) {
332 fop->op.func.op = FFUNC_DROP;
333 ret = E_SUCCESS;
334 } else
335 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
336 } else if (!strcmp(name, "kill")) {
337 if (nargs == 0) {
338 fop->op.func.op = FFUNC_KILL;
339 ret = E_SUCCESS;
340 } else
341 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
342 } else if (!strcmp(name, "msg")) {
343 if (nargs == 1) {
344 fop->op.func.op = FFUNC_MSG;
345 fop->op.func.string = (u_char*)strdup(dec_args[0]);
346 fop->op.func.slen = strescape((char*)fop->op.func.string,
347 (char*)fop->op.func.string, strlen(fop->op.func.string)+1);
348 ret = E_SUCCESS;
349 } else
350 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
351 } else if (!strcmp(name, "exec")) {
352 if (nargs == 1) {
353 fop->op.func.op = FFUNC_EXEC;
354 fop->op.func.string = (u_char*)strdup(dec_args[0]);
355 fop->op.func.slen = strlen((const char*)fop->op.func.string);
356 ret = E_SUCCESS;
357 } else
358 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
359 } else if (!strcmp(name, "exit")) {
360 if (nargs == 0) {
361 fop->opcode = FOP_EXIT;
362 ret = E_SUCCESS;
363 } else
364 SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name);
365 }
366
367 /* free the array */
368 for (i = 0; i < nargs; i++)
369 SAFE_FREE(dec_args[i]);
370
371 SAFE_FREE(dec_args);
372 SAFE_FREE(str);
373 return ret;
374 }
375
376 /*
377 * split the args of a function and return
378 * the number of found args
379 */
380 static char ** decode_args(char *args, int *nargs)
381 {
382 char *p, *q, *arg;
383 int i = 0;
384 char **parsed;
385
386 *nargs = 0;
387
388 /* get the end */
389 if ((p = strrchr(args, ')')) != NULL)
390 *p = '\0';
391
392 /* trim the empty spaces */
393 for (; *args == ' '; args++);
394 for (q = args + strlen(args) - 1; *q == ' '; q--)
395 *q = '\0';
396
397 /* there are no arguments */
398 if (!strchr(args, ',') && strlen(args) == 0)
399 return NULL;
400
401 SAFE_CALLOC(parsed, 1, sizeof(char *));
402
403 /* split the arguments */
404 for (p = strsep_quotes(&args, ','), i = 1; p != NULL; p = strsep_quotes(&args, ','), i++) {
405
406 /* alloc the array for the arguments */
407 SAFE_REALLOC(parsed, (i + 1) * sizeof(char *));
408
409 /* trim the empty spaces */
410 for (arg = p; *arg == ' '; arg++);
411 for (q = arg + strlen(arg) - 1; *q == ' '; q--)
412 *q = '\0';
413
414 /* remove the quotes (if there are) */
415 if (*arg == '\"' && arg[strlen(arg) - 1] == '\"') {
416 arg[strlen(arg) - 1] = '\0';
417 arg++;
418 }
419 /* put in in the array */
420 parsed[i - 1] = strdup(arg);
421
422 ef_debug(5, "ARGUMENT: %s\n", arg);
423 }
424
425 /* return the number of args */
426 *nargs = i - 1;
427
428 return parsed;
429 }
430
431
432
433 /*
434 * split the string in tokens separated by 'delim'.
435 * ignore 'delim' if it is between two quotes "..."
436 */
437 static char * strsep_quotes(char **stringp, const char delim)
438 {
439 char *s;
440 int c;
441 char *tok;
442
443 /* sanity check */
444 if ((s = *stringp) == NULL)
445 return (NULL);
446
447 /* parse the string */
448 for (tok = s;;) {
449
450 /* XXX -
451 * this does not parses correctly string in the form:
452 *
453 * "foo, bar, "tic,tac""
454 */
455
456 /* skip string between quotes */
457 if (*s == '\"')
458 while(*(++s) != '\"' && *s != '\0');
459
460 c = *s++;
461
462 /* search for the delimiter */
463 if ( c == delim || c == 0) {
464 if (c == 0)
465 s = NULL;
466 else
467 s[-1] = 0;
468
469 *stringp = s;
470
471 return (tok);
472 }
473 }
474 /* NOTREACHED */
475 }
476
477 /* EOF */
478
479 // vim:ts=3:expandtab
480