"Fossies" - the Fresh Open Source Software Archive 
Member "ettercap-0.8.3.1/utils/etterlog/el_log.c" (1 Aug 2020, 11722 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 "el_log.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 etterlog -- read the logfile
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 <el.h>
23 #include <ec_log.h>
24
25 void open_log(char *file);
26 int get_header(struct log_global_header *hdr);
27 int get_packet(struct log_header_packet *pck, u_char **buf);
28 int get_info(struct log_header_info *inf, struct dissector_info *buf);
29 static int put_header(gzFile fd, struct log_global_header *hdr);
30 static int put_packet(gzFile fd, struct log_header_packet *pck, u_char *buf);
31 static int put_info(gzFile fd, struct log_header_info *inf, struct dissector_info *buf);
32 void concatenate(int argc, char **argv);
33 static void dump_file(gzFile fd, struct log_global_header *hdr);
34
35 /*******************************************/
36
37 /*
38 * open the logfile, then drop the privs
39 */
40
41 void open_log(char *file)
42 {
43 int zerr;
44
45 EL_GBL_LOGFILE = strdup(file);
46 EL_GBL_LOG_FD = gzopen(file, "rb");
47 if(EL_GBL_LOG_FD == Z_NULL)
48 FATAL_ERROR("Cannot read the log file, please ensure you have enough permissions to read %s: error %s", file, gzerror(EL_GBL_LOG_FD, &zerr));
49 }
50
51 /*
52 * returns the global header
53 */
54
55 int get_header(struct log_global_header *hdr)
56 {
57 int c;
58
59 c = gzread(EL_GBL_LOG_FD, hdr, sizeof(struct log_global_header));
60
61 if (c != sizeof(struct log_global_header))
62 return -E_INVALID;
63
64 /* convert to host order */
65
66 hdr->magic = ntohs(hdr->magic);
67
68 if (hdr->magic != EC_LOG_MAGIC)
69 return -E_INVALID;
70
71 hdr->first_header = ntohs(hdr->first_header);
72 gzseek(EL_GBL_LOG_FD, hdr->first_header, SEEK_SET);
73
74 /* adjust the timestamp */
75 hdr->tv.tv_sec = ntohl(hdr->tv.tv_sec);
76 hdr->tv.tv_usec = ntohl(hdr->tv.tv_usec);
77
78 hdr->type = ntohl(hdr->type);
79
80 return E_SUCCESS;
81 }
82
83 /*
84 * store the header in a file
85 */
86 static int put_header(gzFile fd, struct log_global_header *hdr)
87 {
88 int c;
89
90 /* convert to network order */
91 hdr->magic = htons(hdr->magic);
92 hdr->first_header = htons(hdr->first_header);
93 hdr->tv.tv_sec = htonl(hdr->tv.tv_sec);
94 hdr->tv.tv_usec = htonl(hdr->tv.tv_usec);
95 hdr->type = htonl(hdr->type);
96
97 c = gzwrite(fd, hdr, sizeof(struct log_global_header));
98 if (c != sizeof(struct log_global_header))
99 FATAL_ERROR("Cannot write output file");
100
101 /* convert to host order */
102 hdr->magic = ntohs(hdr->magic);
103 hdr->first_header = ntohs(hdr->first_header);
104 hdr->tv.tv_sec = ntohl(hdr->tv.tv_sec);
105 hdr->tv.tv_usec = ntohl(hdr->tv.tv_usec);
106 hdr->type = ntohl(hdr->type);
107
108 return E_SUCCESS;
109 }
110
111
112 /*
113 * read the header of a packet
114 * and return the data in the buf
115 */
116 int get_packet(struct log_header_packet *pck, u_char **buf)
117 {
118 int c;
119
120 c = gzread(EL_GBL_LOG_FD, pck, sizeof(struct log_header_packet));
121
122 if (c != sizeof(struct log_header_packet))
123 return -E_INVALID;
124
125 pck->len = ntohl(pck->len);
126
127 /* adjust the timestamp */
128 pck->tv.tv_sec = ntohl(pck->tv.tv_sec);
129 pck->tv.tv_usec = ntohl(pck->tv.tv_usec);
130
131 /* allocate the memory for the buffer */
132 SAFE_CALLOC(*buf, pck->len, sizeof(u_char));
133
134 /* copy the data of the packet */
135 c = gzread(EL_GBL_LOG_FD, *buf, pck->len);
136
137 if ((size_t)c != pck->len)
138 return -E_INVALID;
139
140 return E_SUCCESS;
141 }
142
143 /*
144 * store a packet into a file
145 */
146 static int put_packet(gzFile fd, struct log_header_packet *pck, u_char *buf)
147 {
148 int c;
149
150 pck->len = htonl(pck->len);
151 pck->tv.tv_sec = htonl(pck->tv.tv_sec);
152 pck->tv.tv_usec = htonl(pck->tv.tv_usec);
153
154 c = gzwrite(fd, pck, sizeof(struct log_header_packet));
155 if (c != sizeof(struct log_header_packet))
156 return -E_INVALID;
157
158 pck->len = ntohl(pck->len);
159 pck->tv.tv_sec = ntohl(pck->tv.tv_sec);
160 pck->tv.tv_usec = ntohl(pck->tv.tv_usec);
161
162 /* copy the data of the packet */
163 c = gzwrite(fd, buf, pck->len);
164 if ((size_t)c != pck->len)
165 return -E_INVALID;
166
167 return E_SUCCESS;
168 }
169
170 /*
171 * read the header for the info and
172 * return the user, pass ecc in buf
173 */
174 int get_info(struct log_header_info *inf, struct dissector_info *buf)
175 {
176 int c;
177
178 /* get the whole header */
179 c = gzread(EL_GBL_LOG_FD, inf, sizeof(struct log_header_info));
180
181 /* truncated ? */
182 if (c != sizeof(struct log_header_info))
183 return -E_INVALID;
184
185 /* adjust the variable lengths */
186 inf->var.user_len = ntohs(inf->var.user_len);
187 inf->var.pass_len = ntohs(inf->var.pass_len);
188 inf->var.info_len = ntohs(inf->var.info_len);
189 inf->var.banner_len = ntohs(inf->var.banner_len);
190
191 /*
192 * get the dissectors info
193 *
194 * we can deal only with associated user and pass,
195 * so there must be present all of them
196 */
197
198 if (inf->var.user_len) {
199 SAFE_CALLOC(buf->user, inf->var.user_len + 1, sizeof(char));
200
201 c = gzread(EL_GBL_LOG_FD, buf->user, inf->var.user_len);
202 if (c != inf->var.user_len)
203 return -E_INVALID;
204 }
205
206 if (inf->var.pass_len) {
207 SAFE_CALLOC(buf->pass, inf->var.pass_len + 1, sizeof(char));
208
209 c = gzread(EL_GBL_LOG_FD, buf->pass, inf->var.pass_len);
210 if (c != inf->var.pass_len)
211 return -E_INVALID;
212 }
213
214 if (inf->var.info_len) {
215 SAFE_CALLOC(buf->info, inf->var.info_len + 1, sizeof(char));
216
217 c = gzread(EL_GBL_LOG_FD, buf->info, inf->var.info_len);
218 if (c != inf->var.info_len)
219 return -E_INVALID;
220 }
221
222 if (inf->var.banner_len) {
223 SAFE_CALLOC(buf->banner, inf->var.banner_len + 1, sizeof(char));
224
225 c = gzread(EL_GBL_LOG_FD, buf->banner, inf->var.banner_len);
226 if (c != inf->var.banner_len)
227 return -E_INVALID;
228 }
229
230 /*
231 * sanity check for ip_addr struct
232 */
233 switch (ntohs(inf->L3_addr.addr_type)) {
234 case AF_INET:
235 if (ntohs(inf->L3_addr.addr_len) != IP_ADDR_LEN)
236 return -E_INVALID;
237 break;
238 case AF_INET6:
239 if (ntohs(inf->L3_addr.addr_len) != IP6_ADDR_LEN)
240 return -E_INVALID;
241 break;
242 default:
243 return -E_INVALID;
244 }
245
246 /* if client IP address has been set otherwise skip */
247 if (!ip_addr_is_zero(&inf->client)) {
248 switch (ntohs(inf->client.addr_type)) {
249 case AF_INET:
250 if (ntohs(inf->client.addr_len) != IP_ADDR_LEN)
251 return -E_INVALID;
252 break;
253 case AF_INET6:
254 if (ntohs(inf->client.addr_len) != IP6_ADDR_LEN)
255 return -E_INVALID;
256 break;
257 default:
258 return -E_INVALID;
259 }
260 }
261
262
263 return E_SUCCESS;
264 }
265
266 /*
267 * store a info struct into a file
268 */
269 static int put_info(gzFile fd, struct log_header_info *inf, struct dissector_info *buf)
270 {
271 int c;
272
273 /* adjust the variable lengths */
274 inf->var.user_len = htons(inf->var.user_len);
275 inf->var.pass_len = htons(inf->var.pass_len);
276 inf->var.info_len = htons(inf->var.info_len);
277 inf->var.banner_len = htons(inf->var.banner_len);
278
279 /* write the header */
280 c = gzwrite(fd, inf, sizeof(struct log_header_info));
281 if (c != sizeof(struct log_header_info))
282 return -E_INVALID;
283
284 /* reconvert for internal use */
285 inf->var.user_len = ntohs(inf->var.user_len);
286 inf->var.pass_len = ntohs(inf->var.pass_len);
287 inf->var.info_len = ntohs(inf->var.info_len);
288 inf->var.banner_len = ntohs(inf->var.banner_len);
289
290 /* write the data */
291 if (inf->var.user_len) {
292 c = gzwrite(fd, buf->user, inf->var.user_len);
293 if (c != inf->var.user_len)
294 return -E_INVALID;
295 }
296
297 if (inf->var.pass_len) {
298 c = gzwrite(fd, buf->pass, inf->var.pass_len);
299 if (c != inf->var.pass_len)
300 return -E_INVALID;
301 }
302
303 if (inf->var.info_len) {
304 c = gzwrite(fd, buf->info, inf->var.info_len);
305 if (c != inf->var.info_len)
306 return -E_INVALID;
307 }
308
309 if (inf->var.banner_len) {
310 c = gzwrite(fd, buf->banner, inf->var.banner_len);
311 if (c != inf->var.banner_len)
312 return -E_INVALID;
313 }
314
315 return E_SUCCESS;
316 }
317
318 /*
319 * concatenate two (or more) files into one single file
320 */
321 void concatenate(int argc, char **argv)
322 {
323 int zerr;
324 gzFile fd;
325 struct log_global_header hdr, tmp;
326
327 memset(&hdr, 0, sizeof(struct log_global_header));
328
329 /* open the output file for writing */
330 fd = gzopen(EL_GBL_LOGFILE, "wb");
331 ON_ERROR(fd, NULL, "%s", gzerror(fd, &zerr));
332
333 /*
334 * use EL_GBL_LOG_FD here so the get_header function
335 * will use this file
336 */
337 EL_GBL_LOG_FD = gzopen(argv[argc], "rb");
338 ON_ERROR(EL_GBL_LOG_FD, NULL, "%s", gzerror(EL_GBL_LOG_FD, &zerr));
339
340 /* get the file header */
341 if (get_header(&hdr) != E_SUCCESS)
342 FATAL_ERROR("Invalid log file (%s)", argv[argc]);
343
344 /* write the header */
345 put_header(fd, &hdr);
346
347 USER_MSG("Concatenating file [%s]", argv[argc]);
348
349 /* copy the first file into the output */
350 dump_file(fd, &hdr);
351
352 /* move the pointer to the next file */
353 argc++;
354
355 /* cicle thru the file list */
356 while(argv[argc] != NULL) {
357
358 EL_GBL_LOG_FD = gzopen(argv[argc], "rb");
359 ON_ERROR(EL_GBL_LOG_FD, NULL, "%s", gzerror(EL_GBL_LOG_FD, &zerr));
360
361 /* get the file header */
362 if (get_header(&tmp) != E_SUCCESS)
363 FATAL_ERROR("Invalid log file (%s)", argv[argc]);
364
365 /* check if the files are compatible */
366 if (hdr.type != tmp.type)
367 FATAL_ERROR("Cannot concatenate different type of file");
368
369 USER_MSG("Concatenating file [%s]", argv[argc]);
370
371 /* concatenate this file */
372 dump_file(fd, &tmp);
373
374 gzclose(EL_GBL_LOG_FD);
375 argc++;
376 }
377
378 gzclose(fd);
379
380 USER_MSG("\nAll files concatenated into: %s\n\n", EL_GBL_LOGFILE);
381
382 el_exit(0);
383 }
384
385
386 /*
387 * dump the file into the fd
388 */
389 static void dump_file(gzFile fd, struct log_global_header *hdr)
390 {
391 struct log_header_packet pck;
392 struct log_header_info inf;
393 struct dissector_info infbuf;
394 u_char *pckbuf;
395 int count = 0;
396
397
398 memset(&pck,0,sizeof(struct log_header_packet));
399 memset(&inf,0,sizeof(struct log_header_info));
400 memset(&infbuf,0,sizeof(struct dissector_info));
401
402 /* loop until EOF */
403 LOOP {
404 switch (hdr->type) {
405 case LOG_INFO:
406 if (get_info(&inf, &infbuf) != E_SUCCESS) {
407 USER_MSG("\n");
408 return;
409 }
410 /* write the info */
411 put_info(fd, &inf, &infbuf);
412 SAFE_FREE(infbuf.user);
413 SAFE_FREE(infbuf.pass);
414 SAFE_FREE(infbuf.info);
415 SAFE_FREE(infbuf.banner);
416
417 break;
418
419 case LOG_PACKET:
420 if (get_packet(&pck, &pckbuf) != E_SUCCESS) {
421 USER_MSG("\n");
422 return;
423 }
424 /* write the data */
425 put_packet(fd, &pck, pckbuf);
426 SAFE_FREE(pckbuf);
427 break;
428
429 default:
430 FATAL_ERROR("Unknown log type");
431 break;
432 }
433
434 /* a dot every 10 packets */
435 if (count++ % 10 == 0) {
436 USER_MSG(".");
437 fflush(stdout);
438 }
439 }
440
441 }
442
443
444 /* EOF */
445
446 // vim:ts=3:expandtab
447