1 #include "xprobe.h"
2 #include <stdarg.h>
3 #include "interface.h"
4 #include "cmd_opts.h"
5 #include "xprobe_module.h"
6 #include "log.h"
7
write(const char * fmt,...)8 int Log::write(const char *fmt, ...) {
9 va_list va;
10
11 va_start(va, fmt);
12 if (logopened)
13 return vfprintf(ofile, fmt, va);
14 else
15 return 0;
16 }
17
open()18 int Log::open() {
19 if ((ofile = fopen(logfile.c_str(), "w")) == NULL) {
20 ui->msg("fopen(): %s\n", strerror(errno));
21 return 1;
22 }
23 logopened = true;
24 return 0;
25 }
26
log(unsigned int type,const char * fmt,...)27 int XML_Log::log(unsigned int type, const char *fmt, ...) {
28 va_list varg;
29 va_start(varg, fmt);
30 if (!is_opened())
31 return 0;
32 switch(type) {
33 case XPROBELOG_XP_SESS_START:
34 write_tabs();
35 tags_opened++;
36 log_start(fmt, varg);
37 break;
38 case XPROBELOG_MSG_RUN:
39 write_tabs();
40 log_run(fmt, varg);
41 break;
42 case XPROBELOG_MOD_SESS_START:
43 write_tabs();
44 tags_opened++;
45 if (fmt)
46 write("<modules caption=\"%s\">\n", fmt);
47 break;
48 case XPROBELOG_MSG_MODULE:
49 write_tabs();
50 log_module(fmt, varg);
51 break;
52 case XPROBELOG_MOD_SESS_END:
53 tags_opened--;
54 write_tabs();
55 write("</modules>\n");
56 break;
57 case XPROBELOG_TG_SESS_START:
58 write_tabs();
59 tags_opened++;
60 log_target(fmt, varg);
61 break;
62 case XPROBELOG_REACH_SESS_START:
63 write_tabs();
64 tags_opened++;
65 write("<reachability>\n");
66 break;
67 case XPROBELOG_MSG_STATE:
68 write_tabs();
69 log_state(fmt, varg);
70 break;
71 case XPROBELOG_MSG_RTT:
72 write_tabs();
73 log_rtt(fmt, varg);
74 break;
75 case XPROBELOG_REACH_SESS_END:
76 tags_opened--;
77 write_tabs();
78 write("</reachability>\n");
79 break;
80 case XPROBELOG_INFO_SESS_START:
81 write_tabs();
82 tags_opened++;
83 write("<information_gathering>\n");
84 break;
85 case XPROBELOG_PS_SESS_START:
86 write_tabs();
87 tags_opened++;
88 log_pscan(fmt, varg);
89 break;
90 case XPROBELOG_STATS_SESS_START:
91 write_tabs();
92 tags_opened++;
93 write("<stats>\n");
94 break;
95 case XPROBELOG_MSG_PS_TCPST:
96 write_tabs();
97 log_port_stats(6, fmt, varg);
98 break;
99 case XPROBELOG_MSG_PS_UDPST:
100 write_tabs();
101 log_port_stats(17, fmt, varg);
102 break;
103 case XPROBELOG_STATS_SESS_END:
104 tags_opened--;
105 write_tabs();
106 write("</stats>\n");
107 break;
108 case XPROBELOG_PSDET_SESS_START:
109 write_tabs();
110 tags_opened++;
111 write("<details>\n");
112 break;
113 case XPROBELOG_MSG_PORT:
114 write_tabs();
115 log_port(fmt, varg);
116 break;
117 case XPROBELOG_PSDET_SESS_END:
118 tags_opened--;
119 write_tabs();
120 write("</details>\n");
121 break;
122 case XPROBELOG_PS_SESS_END:
123 tags_opened--;
124 write_tabs();
125 write("</portscan>\n");
126 break;
127 case XPROBELOG_INFO_SESS_END:
128 tags_opened--;
129 write_tabs();
130 write("</information_gathering>\n");
131 break;
132 case XPROBELOG_GUESS_SESS_START:
133 write_tabs();
134 tags_opened++;
135 write("<os_guess>\n");
136 break;
137 case XPROBELOG_MSG_PRIMARY:
138 case XPROBELOG_MSG_SECONDARY:
139 write_tabs();
140 log_guess(type, fmt, varg);
141 break;
142 case XPROBELOG_GUESS_SESS_END:
143 tags_opened--;
144 write_tabs();
145 write("</os_guess>\n");
146 break;
147 case XPROBELOG_TG_SESS_END:
148 tags_opened--;
149 write_tabs();
150 write("</target>\n");
151 break;
152 case XPROBELOG_XP_SESS_END:
153 tags_opened--;
154 write_tabs();
155 write("</Xprobe2>");
156 break;
157 case XPROBELOG_OTHER_TCPP:
158 case XPROBELOG_OTHER_UDPP:
159 write_tabs();
160 log_other_ports(type, fmt, varg);
161 break;
162 default:
163 ui->error("Unknown XML message type %d\n", type);
164 return FAIL;
165 }
166 return OK;
167 }
168
169 /* s-state */
log_other_ports(char type,const char * fmt,va_list varg)170 int XML_Log::log_other_ports(char type, const char *fmt, va_list varg) {
171 int st=-1;
172 const char *state=NULL;
173
174 while(*fmt)
175 switch (*fmt++) {
176 case 's':
177 st = va_arg(varg, int);
178 break;
179 }
180 if (st > -1) {
181 switch(st) {
182 case XPROBE_TARGETP_CLOSED:
183 state="closed";
184 break;
185 case XPROBE_TARGETP_OPEN:
186 state="open";
187 break;
188 case XPROBE_TARGETP_FILTERED:
189 state="filtered";
190 break;
191 default:
192 state = "unknown";
193 }
194 write("<other proto=\"%s\" state=\"%s\"/>\n", type == XPROBELOG_OTHER_TCPP ? "tcp" : "udp", state);
195 return OK;
196 } else
197 return FAIL;
198 }
199
200 /* p-probability, s-caption */
log_guess(int type,const char * fmt,va_list varg)201 int XML_Log::log_guess(int type, const char *fmt, va_list varg) {
202 int prob=-1;
203 char *os=NULL;
204 const char *tp = type == XPROBELOG_MSG_PRIMARY ? "primary" : "secondary";
205
206 while(*fmt)
207 switch(*fmt++) {
208 case 'p':
209 prob = va_arg(varg, int);
210 break;
211 case 's':
212 os = va_arg(varg, char *);
213 break;
214 }
215 if (os && prob > -1) {
216 write("<%s probability=\"%d\" unit=\"percent\"> %s </%s>\n", tp, prob, os, tp);
217 return OK;
218 } else
219 return FAIL;
220 }
221
222 /* n-number, p-proto, t-state, s-service */
log_port(const char * fmt,va_list varg)223 int XML_Log::log_port(const char *fmt, va_list varg) {
224 int portnum=-1, proto=-1, st=-1;
225 char *state=NULL, *service=NULL;
226
227 while (*fmt)
228 switch(*fmt++) {
229 case 'n':
230 portnum = va_arg(varg, int);
231 break;
232 case 'p':
233 proto = va_arg(varg, int);
234 break;
235 case 't':
236 st= va_arg(varg, int);
237 break;
238 case 's':
239 service = va_arg(varg, char *);
240 break;
241 }
242 if (service && portnum > -1 && proto > -1 && st > -1) {
243 switch(st) {
244 case XPROBE_TARGETP_CLOSED:
245 state="closed";
246 break;
247 case XPROBE_TARGETP_OPEN:
248 state="open";
249 break;
250 case XPROBE_TARGETP_FILTERED:
251 state="filtered";
252 break;
253 default:
254 state="unknown";
255 }
256 write("<port number=\"%d\" proto=\"%s\" state=\"%s\" service=\"%s\" />\n", portnum, proto==IPPROTO_TCP ? "tcp" : "udp", state, service);
257 return OK;
258 } else
259 return FAIL;
260
261 }
262
263 /* o-open, c-closed, f-filtered */
log_port_stats(char proto,const char * fmt,va_list varg)264 int XML_Log::log_port_stats(char proto, const char *fmt, va_list varg) {
265 int opn=-1, closed=-1, filtered=-1;
266
267 while(*fmt)
268 switch(*fmt++) {
269 case 'o':
270 opn = va_arg(varg, int);
271 break;
272 case 'c':
273 closed = va_arg(varg, int);
274 break;
275 case 'f':
276 filtered = va_arg(varg, int);
277 break;
278 }
279 if (opn > -1 && closed > -1 && filtered > -1) {
280 write("<%s open=\"%d\" closed=\"%d\" filtered=\"%d\"/>\n", proto == 6 ? "tcp" : "udp", opn, closed, filtered);
281 return OK;
282 } else
283 return FAIL;
284
285 }
286
log_pscan(const char * fmt,va_list varg)287 int XML_Log::log_pscan(const char *fmt, va_list varg) {
288 double duration=-1;
289
290 while(*fmt)
291 switch(*fmt++) {
292 case 'd':
293 duration = va_arg(varg, double);
294 break;
295 }
296 if (duration > -1) {
297 write("<portscan duration=\"P%.5fS\">\n", duration);
298 return OK;
299 } else
300 return FAIL;
301 }
302
303 /* r-real, s-selected */
log_rtt(const char * fmt,va_list varg)304 int XML_Log::log_rtt(const char *fmt, va_list varg) {
305 double real=-1, selected=-1;
306
307 while (*fmt)
308 switch(*fmt++) {
309 case 'r':
310 real = va_arg(varg, double);
311 break;
312 case 's':
313 selected = va_arg(varg, double);
314 break;
315 }
316 if (real > -1 && selected > -1) {
317 write("<rtt real=\"P%.5fS\" selected=\"P%.5fS\"/>\n", real, selected);
318 return OK;
319 } else
320 return FAIL;
321 }
322 /* s-state,p-probability */
log_state(const char * fmt,va_list varg)323 int XML_Log::log_state(const char *fmt, va_list varg) {
324 char *state=NULL;
325 int prob=-1;
326
327 while(*fmt)
328 switch(*fmt++) {
329 case 's':
330 state = va_arg(varg, char *);
331 break;
332 case 'p':
333 prob = va_arg(varg, int);
334 break;
335 }
336 if (state && prob> -1) {
337 write("<state state=\"%s\" probability=\"%d\" unit=\"percent\"/>\n", state, prob);
338 return OK;
339 } else
340 return FAIL;
341 }
342
343 /* a-address */
log_target(const char * fmt,va_list varg)344 int XML_Log::log_target(const char *fmt, va_list varg) {
345 char *addr=NULL;
346
347 while (*fmt)
348 switch(*fmt++) {
349 case 'a':
350 addr = va_arg(varg, char *);
351 break;
352 }
353 if (addr) {
354 write("<target ip=\"%s\">\n", addr);
355 return OK;
356 } else
357 return FAIL;
358 }
359
360 /* t-type, n-name, d-modnumber, s-caption */
log_module(const char * fmt,va_list varg)361 int XML_Log::log_module(const char *fmt, va_list varg) {
362 char *name=NULL, *caption=NULL;
363 int modnum=-1, type=-1;
364 const char *tp=NULL;
365
366 while (*fmt)
367 switch(*fmt++) {
368 case 't':
369 type = va_arg(varg, int);
370 break;
371 case 'n':
372 name = va_arg(varg, char *);
373 break;
374 case 'd':
375 modnum = va_arg(varg, int);
376 break;
377 case 's':
378 caption = va_arg(varg, char *);
379 break;
380 }
381 if (type > -1 && name && caption && modnum > -1) {
382 switch(type) {
383 case XPROBE_MODULE_ALIVETEST:
384 tp="reachability";
385 break;
386 case XPROBE_MODULE_OSTEST:
387 tp ="fingerprinting";
388 break;
389 case XPROBE_MODULE_INFOGATHER:
390 tp ="information gathering";
391 break;
392 default:
393 tp="unknown";
394 }
395 write("<module type=\"%s\" name=\"%s\" number=\"%d\"> %s </module>\n", tp, name, modnum, caption);
396 return OK;
397 } else
398 return FAIL;
399 }
400
401
402 /* c-count(argc), a-arguments(argv), d-datetime */
log_run(const char * fmt,va_list varg)403 int XML_Log::log_run(const char *fmt, va_list varg) {
404 char **argv=NULL;
405 time_t date=0;
406 int argc=-1, k, hr, min;
407 struct tm *tms=NULL;
408
409 while(*fmt)
410 switch(*fmt++) {
411 case 'c':
412 argc = va_arg(varg, int);
413 break;
414 case 'a':
415 argv = va_arg(varg, char **);
416 break;
417 case 'd':
418 date = va_arg(varg, time_t);
419 }
420 if (argv && date && argc > -1) {
421 write("<run arguments=\"");
422 for (k=0; k < argc; k++)
423 write("%s ", argv[k]);
424 tms = localtime(&date);
425 // 2003-04-02T14:39:01-05:00
426 if (tms) {
427 hr = (tms->tm_gmtoff / 60) / 60;
428 min = (tms->tm_gmtoff / 60) % 60;
429
430 write("\" date=\"%d-%.2d-%.2dT%.2d:%.2d:%.2d%s%.2d:%.2d\"/>\n",
431 tms->tm_year+1900, tms->tm_mon+1, tms->tm_mday,
432 tms->tm_hour, tms->tm_min, tms->tm_sec,
433 tms->tm_gmtoff < 0 ? "-" : "+", hr, min);
434 }
435 return OK;
436 } else
437 return FAIL;
438 }
439
440 /* v-version; b-banner */
log_start(const char * fmt,va_list varg)441 int XML_Log::log_start(const char *fmt, va_list varg) {
442 char *ver=NULL, *banner=NULL;
443
444 while (*fmt)
445 switch(*fmt++) {
446 case 'v': // version
447 ver = va_arg(varg, char *);
448 break;
449 case 'b': // banner
450 banner = va_arg(varg, char *);
451 break;
452 }
453 if (ver && banner) {
454 write("<?xml version=\"1.0\"?>\n<Xprobe2 version=\"%s\">\n<!-- %s -->\n", ver, banner);
455 return OK;
456 } else
457 return FAIL;
458 }
459