1 /*
2 etterlog -- decode a stream and extract file from it
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
23 #include <el.h>
24 #include <el_functions.h>
25
26 #include <fcntl.h>
27 #ifdef HAVE_LIBGEN_H
28 #include <libgen.h>
29 #endif
30
31 #ifdef OS_WINDOWS
32 #define MKDIR(path,acc) mkdir(path)
33 #else
34 #define MKDIR(path,acc) mkdir(path,acc)
35 #endif
36
37 /* globals */
38
39 static SLIST_HEAD (, dec_entry) extractor_table;
40
41 struct dec_entry {
42 u_int8 level;
43 u_int32 type;
44 FUNC_EXTRACTOR_PTR(extractor);
45 SLIST_ENTRY (dec_entry) next;
46 };
47
48 /*******************************************/
49
50 /*
51 * decode the stream
52 */
decode_stream(struct stream_object * so)53 int decode_stream(struct stream_object *so)
54 {
55 struct so_list *pl;
56 FUNC_EXTRACTOR_PTR(app_extractor);
57 int ret = 0;
58
59 /* get the port used by the stream, looking at the first packet */
60 pl = TAILQ_FIRST(&so->so_head);
61
62 /*
63 * we should run the extractor on both the tcp/udp ports
64 * since we may be interested in both client and server traffic.
65 */
66 switch (pl->po.L4.proto) {
67 case NL_TYPE_TCP:
68 app_extractor = get_extractor(APP_LAYER_TCP, ntohs(pl->po.L4.src));
69 EXECUTE_EXTRACTOR(app_extractor, so, ret);
70 app_extractor = get_extractor(APP_LAYER_TCP, ntohs(pl->po.L4.dst));
71 EXECUTE_EXTRACTOR(app_extractor, so, ret);
72 break;
73
74 case NL_TYPE_UDP:
75 app_extractor = get_extractor(APP_LAYER_UDP, ntohs(pl->po.L4.src));
76 EXECUTE_EXTRACTOR(app_extractor, so, ret);
77 app_extractor = get_extractor(APP_LAYER_UDP, ntohs(pl->po.L4.dst));
78 EXECUTE_EXTRACTOR(app_extractor, so, ret);
79 break;
80 }
81
82 /* if at least one extractor has found something ret is positive */
83 return ret;
84 }
85
86
87 /*
88 * add a extractor to the extractors table
89 */
add_extractor(u_int8 level,u_int32 type,FUNC_EXTRACTOR_PTR (extractor))90 void add_extractor(u_int8 level, u_int32 type, FUNC_EXTRACTOR_PTR(extractor))
91 {
92 struct dec_entry *e;
93
94 SAFE_CALLOC(e, 1, sizeof(struct dec_entry));
95
96 e->level = level;
97 e->type = type;
98 e->extractor = extractor;
99
100 SLIST_INSERT_HEAD(&extractor_table, e, next);
101
102 return;
103 }
104
105
106 /*
107 * get a extractor from the extractors table
108 */
get_extractor(u_int8 level,u_int32 type)109 void * get_extractor(u_int8 level, u_int32 type)
110 {
111 struct dec_entry *e;
112 void *ret;
113
114 SLIST_FOREACH (e, &extractor_table, next) {
115 if (e->level == level && e->type == type) {
116 ret = (void *)e->extractor;
117 return ret;
118 }
119 }
120
121 return NULL;
122 }
123
124 /*
125 * open a file to write into.
126 * the file are saved in a subdirectories structure like this:
127 * - host
128 * - proto
129 * - stealed_file
130 * e.g.:
131 * - 192.168.0.1
132 * - HTTP
133 * - images
134 * - a.gif
135 * - b.gif
136 * - styles
137 * - style.css
138 * - index.html
139 * - foo.php
140 */
decode_to_file(char * host,char * proto,char * file)141 int decode_to_file(char *host, char *proto, char *file)
142 {
143 #define BASE_DIR "./decoded_files"
144 char dir[1024];
145 char *p;
146 char *path = strdup(file);
147 char *filetmp = strdup(file);
148 int fd;
149
150 /* always create the base, host and proto directory */
151 strcpy(dir, BASE_DIR);
152 MKDIR(dir, 0700);
153 strlcat(dir, "/", sizeof(dir));
154 strlcat(dir, host, sizeof(dir));
155 MKDIR(dir, 0700);
156 strlcat(dir, "/", sizeof(dir));
157 strlcat(dir, proto, sizeof(dir));
158 MKDIR(dir, 0700);
159
160 /* now 'dir' contains "BASE_DIR/host/proto" */
161
162 /* parse the file to be created and create the required subdirectories */
163 for (p = strsep(&path, "/"); p != NULL; p = strsep(&path, "/")) {
164 strlcat(dir, "/", sizeof(dir));
165 strlcat(dir, p, sizeof(dir));
166
167 /* the token is a directory, create it */
168 if (strcmp(p, basename(filetmp))) {
169 MKDIR(dir, 0700);
170 } else {
171 /* exit the parsing and open the file */
172 break;
173 }
174 }
175
176 /* actually open the file */
177 fd = open(dir, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600);
178
179 SAFE_FREE(filetmp);
180 SAFE_FREE(path);
181
182 return fd;
183 }
184
185
186 /* EOF */
187
188 // vim:ts=3:expandtab
189
190