1 /* Sniffit main program file */
2 /* - by : Brecht Claerhout */
3
4 #include "sn_config.h" /* Config header file */
5
6 #include <unistd.h>
7 #include <signal.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <fcntl.h>
12 /* #include <netdb.h> */
13 #include <errno.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <sys/time.h>
18 #include <netinet/in.h>
19 /* #include <arpa/inet.h> */ /* for inet_addr() */
20 #ifdef INCLUDE_INTERFACE
21 #include <sys/ipc.h>
22 #include <sys/shm.h>
23 #endif
24 #include "pcap.h"
25
26 /************************ Own includes *************************************/
27 #include "sn_defines.h" /* Various defines */
28 #include "sn_structs.h" /* All structures */
29 #include "sn_global.h" /* some global defs */
30 #include "sn_data.h" /* data defs */
31 #include "sn_packets.h" /* My own packet structs */
32 #include "sn_logfile.h"
33 #include "sn_cfgfile.h" /* Config file handling */
34 #include "sn_resolv.h" /* Host resolution */
35 #include "sn_plugins.h" /* Sniffit Plugins file */
36
37 #ifdef INCLUDE_INTERFACE
38 #include "sn_interface.h" /* all ncurses stuff */
39 #endif
40 #ifdef GENERATION
41 #include "sn_generation.h" /* Sniffit Packet generation */
42 #endif
43
44 #include "sniffit.h" /* definition of functions */
45
46 static char Copyright[] =
47 "Sniffit - Brecht Claerhout - Copyright 1996-98";
48
quit(char * prog_name)49 void quit (char *prog_name) /* Learn to use the program */
50 {
51 printf (
52 "usage: %s [-xdabvnN] [-P proto] [-A char] [-p port] [(-r|-R) recordfile]\n"
53 " [-l sniflen] [-L logparam] [-F snifdevice] [-M plugin]\n",
54 prog_name);
55 #ifdef INCLUDE_INTERFACE
56 printf ( " [-D tty]"
57 " (-t<Target IP> | -s<Source IP>)"
58 " | (-i|-I) | -c<config file>]\n");
59 #else
60 printf ( " (-t<Target IP> | -s<Source IP>) | -c<config file>]\n");
61 #endif
62 printf ("Plugins Available:\n");
63 #ifdef PLUGIN0_NAME
64 printf (" 0 -- %s\n", PLUGIN0_NAME);
65 #endif
66 #ifdef PLUGIN1_NAME
67 printf (" 1 -- %s\n", PLUGIN1_NAME);
68 #endif
69 #ifdef PLUGIN2_NAME
70 printf (" 2 -- %s\n", PLUGIN2_NAME);
71 #endif
72 #ifdef PLUGIN3_NAME
73 printf (" 3 -- %s\n", PLUGIN3_NAME);
74 #endif
75 #ifdef PLUGIN4_NAME
76 printf (" 4 -- %s\n", PLUGIN4_NAME);
77 #endif
78 #ifdef PLUGIN5_NAME
79 printf (" 5 -- %s\n", PLUGIN5_NAME);
80 #endif
81 #ifdef PLUGIN6_NAME
82 printf (" 6 -- %s\n", PLUGIN6_NAME);
83 #endif
84 #ifdef PLUGIN7_NAME
85 printf (" 7 -- %s\n", PLUGIN7_NAME);
86 #endif
87 #ifdef PLUGIN8_NAME
88 printf (" 8 -- %s\n", PLUGIN8_NAME);
89 #endif
90 #ifdef PLUGIN9_NAME
91 printf (" 9 -- %s\n", PLUGIN9_NAME);
92 #endif
93
94 exit (0);
95 }
96
97
close_dumpfile(void)98 void close_dumpfile(void) {pcap_dump_close(dev_dump);};
close_pcapdev(void)99 void close_pcapdev(void) {pcap_close(dev_desc);};
100
my_exit(void)101 void my_exit (void)
102 {
103 fflush(NULL);
104 printf("Graceful shutdown...\n");
105 exit (0);
106 };
107
108 /* DEBUGGING INFO */
109 #ifdef DEBUG
close_debug_device(void)110 void close_debug_device (void)
111 {
112 fclose (debug_dev);
113 }
114
debug_msg(char * debug_text)115 void debug_msg (char *debug_text)
116 {
117 fprintf (debug_dev, "%s (%d)\n", debug_text, debug_cnt);
118 debug_cnt++;
119 }
120 #endif
121
strlower(char * string)122 char *strlower (char *string)
123 {
124 int i;
125
126 for (i = 0; i < strlen (string); i++)
127 *(string + i) = (isupper (*(string + i)) ? tolower (*(string + i)) : *(string + i));
128 return string;
129 }
130
start_plugin(int PL_nr,struct Plugin_data * PL_d)131 void start_plugin (int PL_nr, struct Plugin_data *PL_d)
132 {
133 switch (PL_nr)
134 {
135 #ifdef PLUGIN0_NAME
136 case 0:
137 PLUGIN0 (PL_d);
138 break;
139 #endif
140 #ifdef PLUGIN1_NAME
141 case 1:
142 PLUGIN1 (PL_d);
143 break;
144 #endif
145 #ifdef PLUGIN2_NAME
146 case 2:
147 PLUGIN2 (PL_d);
148 break;
149 #endif
150 #ifdef PLUGIN3_NAME
151 case 3:
152 PLUGIN3 (PL_d);
153 break;
154 #endif
155 #ifdef PLUGIN4_NAME
156 case 4:
157 PLUGIN4 (PL_d);
158 break;
159 #endif
160 #ifdef PLUGIN5_NAME
161 case 5:
162 PLUGIN5 (PL_d);
163 break;
164 #endif
165 #ifdef PLUGIN5_NAME
166 case 5:
167 PLUGIN5 (PL_d);
168 break;
169 #endif
170 #ifdef PLUGIN6_NAME
171 case 6:
172 PLUGIN6 (PL_d);
173 break;
174 #endif
175 #ifdef PLUGIN7_NAME
176 case 7:
177 PLUGIN7 (PL_d);
178 break;
179 #endif
180 #ifdef PLUGIN8_NAME
181 case 8:
182 PLUGIN8 (PL_d);
183 break;
184 #endif
185 #ifdef PLUGIN9_NAME
186 case 9:
187 PLUGIN9 (PL_d);
188 break;
189 #endif
190 default:
191 fprintf (stderr, "Plugin does not exist...\n");
192 exit (1);
193 break;
194 }
195 }
196
197 void
reset_all(void)198 reset_all (void)
199 {
200 start_dynam = NULL;
201 dynam_len = 0;
202 }
203
204 /* if do_file == 0, then don't handle the files */
205 /* this is for the global logfile option */
206 struct file_info *
add_dynam(char * file,char ptype,char do_file,_32_bit cur_seq,int len)207 add_dynam (char *file, char ptype, char do_file,
208 _32_bit cur_seq, int len)
209 {
210 int i;
211 FILE *f;
212 int last_time_out = 0;
213 struct file_info *dummy_pointer;
214 struct file_info *search_pointer;
215
216 if (dynam_len >= MAXCOUNT)
217 {
218 /*
219 * remove less effective connection from list
220 */
221 search_pointer = start_dynam;
222 dummy_pointer = start_dynam;
223 do
224 {
225 if (search_pointer->time_out > last_time_out)
226 {
227 last_time_out = search_pointer->time_out;
228 dummy_pointer = search_pointer;
229 }
230 search_pointer = search_pointer->next;
231 }
232 while (search_pointer != NULL);
233 #ifdef DEBUG
234 debug_msg ("Auto timeout engaged (filename follows)");
235 debug_msg (dummy_pointer->filename);
236 #endif
237 if (dummy_pointer->f == NULL)
238 delete_dynam (dummy_pointer->filename, dummy_pointer->proto, 0);
239 else
240 delete_dynam (dummy_pointer->filename, dummy_pointer->proto, 1);
241 printf ("Too many connections... auto timeout\n");
242 }
243 if ((dummy_pointer = (struct file_info *) malloc (sizeof (struct file_info))) == NULL)
244 {
245 printf ("Couldn't allocate memory.\n");
246 exit (0);
247 };
248 dummy_pointer->bytes = 0;
249 dummy_pointer->proto = ptype;
250 strcpy (dummy_pointer->filename, file);
251 if (do_file != 0)
252 {
253 f = fopen (file, "a");
254 if (f == NULL)
255 perror ("Couldn't open logfile:"), exit (0);
256 dummy_pointer->f = f;
257 }
258 else
259 {
260 dummy_pointer->f = NULL;
261 }
262 dummy_pointer->next = NULL;
263 dummy_pointer->buffer = NULL;
264 dummy_pointer->log = 0;
265 dummy_pointer->exp_seq = cur_seq + len;
266 for (i = 0; i < SCBUF; i++)
267 dummy_pointer->scroll_buf[i] = ' ';
268 dummy_pointer->scroll_buf[SCBUF] = 0;
269
270 if (start_dynam == NULL)
271 start_dynam = dummy_pointer;
272 else
273 {
274 search_pointer = start_dynam;
275 while (search_pointer->next != NULL)
276 search_pointer = search_pointer->next;
277 search_pointer->next = dummy_pointer;
278 }
279 dynam_len++;
280 return dummy_pointer;
281 }
282
283 void
delete_dynam(char * file,char ptype,char do_file)284 delete_dynam (char *file, char ptype, char do_file)
285 {
286 struct file_info *search_pointer;
287 struct file_info *dummy_pointer;
288
289 if (start_dynam == NULL)
290 return;
291 search_pointer = start_dynam;
292 if ((strcmp (search_pointer->filename, file) == 0) &&
293 (search_pointer->proto == ptype))
294 {
295 if (do_file != 0)
296 fclose (search_pointer->f);
297 start_dynam = search_pointer->next;
298 dynam_len--;
299 return;
300 }
301 search_pointer = start_dynam;
302 if (search_pointer->next == NULL)
303 return;
304 while (search_pointer->next != NULL)
305 {
306 if ((strcmp (search_pointer->next->filename, file) == 0) &&
307 (search_pointer->next->proto == ptype))
308 {
309 if (do_file != 0)
310 fclose (search_pointer->next->f);
311 dummy_pointer = search_pointer->next;
312 search_pointer->next = search_pointer->next->next;
313 if (dummy_pointer->buffer != NULL)
314 free (dummy_pointer->buffer);
315 free (dummy_pointer);
316 dynam_len--;
317 return;
318 }
319 search_pointer = search_pointer->next;
320 }
321 }
322
323 /* returns NULL on failure */
324 struct file_info *
search_dynam(char * file,char ptype)325 search_dynam (char *file, char ptype)
326 {
327 struct file_info *search_pointer;
328
329 if (start_dynam == NULL)
330 return NULL;
331
332 search_pointer = start_dynam; /* time_out add */
333 do
334 {
335 search_pointer->time_out += 1;
336 search_pointer = search_pointer->next;
337 }
338 while (search_pointer != NULL);
339
340 search_pointer = start_dynam; /* actual search */
341 do
342 {
343 if ((strcmp (search_pointer->filename, file) == 0) &&
344 (search_pointer->proto == ptype))
345 {
346 search_pointer->time_out = 0; /* timeout reset */
347 return search_pointer;
348 }
349 search_pointer = search_pointer->next;
350 }
351 while (search_pointer != NULL);
352 return NULL;
353 }
354
355 /* Type 0: TELNET */
356 void
record_buf(struct file_info * dummy_pointer,_32_bit cur_seq_nr,char * data,int len,int type)357 record_buf (struct file_info *dummy_pointer, _32_bit cur_seq_nr,
358 char *data, int len, int type)
359 {
360 int i, j, noloop = 0;
361
362 if (dummy_pointer->exp_seq != cur_seq_nr)
363 {
364 return;
365 }
366 noloop = 0;
367 for (i = 0; i < len; i++)
368 {
369 j = dummy_pointer->bytes;
370 switch (type)
371 {
372 case 0:
373 if (data[i] == TELNET_ENTER) /* return found */
374 {
375 dummy_pointer->log++;
376 noloop = 1;
377 };
378 break;
379 default:
380 break;
381 }
382 if (noloop == 1)
383 break;
384 if (j >= LOG_PASS_BUF)
385 break;
386 if (isprint (data[i]))
387 {
388 dummy_pointer->buffer[j] = data[i];
389 }
390 else
391 {
392 dummy_pointer->buffer[j] = '~';
393 };
394 dummy_pointer->buffer[j + 1] = 0;
395 dummy_pointer->bytes += 1;
396 }
397 #ifdef DEBUG_ONSCREEN
398 printf ("Record buffer: >%s< (%d)\n", dummy_pointer->buffer, dummy_pointer->bytes);
399 #endif
400 }
401
402 void
sb_shift(struct file_info * dummy_pointer)403 sb_shift (struct file_info *dummy_pointer)
404 {
405 int i, j;
406
407 for (i = 1; i < SCBUF; i++)
408 dummy_pointer->scroll_buf[i - 1] = dummy_pointer->scroll_buf[i];
409 }
410
411 void
sbuf_update(struct file_info * dummy_pointer,_32_bit cur_seq_nr,char * data,int len)412 sbuf_update (struct file_info *dummy_pointer, _32_bit cur_seq_nr,
413 char *data, int len)
414 {
415 int i;
416
417 if (dummy_pointer->exp_seq != cur_seq_nr)
418 {
419 return;
420 }
421
422 for (i = 0; i < len; i++)
423 {
424 sb_shift (dummy_pointer);
425 if (data[i] != 0) /*
426 * used to be 'isprint', not possible for ftp logging
427 */
428 {
429 dummy_pointer->scroll_buf[SCBUF - 1] = data[i];
430 }
431 else
432 {
433 dummy_pointer->scroll_buf[SCBUF - 1] = '.';
434 };
435 }
436 #ifdef DEBUG_ONSCREEN
437 printf ("scr_buf: %s\n", dummy_pointer->scroll_buf);
438 #endif
439 }
440
441 void
print_iphead(struct IP_header * iphead,char icmp_or_plain)442 print_iphead (struct IP_header *iphead, char icmp_or_plain)
443 {
444 int dummy;
445 unsigned char *so, *dest;
446
447 if (icmp_or_plain != 0)
448 printf ("ICMP message concerned following IP packet:\n");
449 so = (unsigned char *) &(iphead->source);
450 dest = (unsigned char *) &(iphead->destination);
451 printf ("from %u.%u.%u.%u to %u.%u.%u.%u\n",
452 so[0], so[1], so[2], so[3],
453 dest[0], dest[1], dest[2], dest[3]);
454 dummy = iphead->type;
455 dummy >>= 5;
456 printf ("IP Packet precedence: %s (%c%c%c)\n",
457 IP_TYPE_precedence[dummy],
458 (iphead->type & IP_DELAY) ? 'D' : '-',
459 (iphead->type & IP_THROUGHPUT) ? 'T' : '-',
460 (iphead->type & IP_RELIABILITY) ? 'R' : '-');
461 dummy = ntohs (iphead->flag_offset);
462 dummy >>= 13;
463 printf ("ID: 0x%X FLAGS: %s %s Time to live (secs): %d\n",
464 ntohs(iphead->ID),
465 (dummy & IP_DF) ? "DF" : "--",
466 (dummy & IP_MF) ? "MF" : "--",
467 iphead->TTL);
468 if (iphead->protocol < 34)
469 printf ("Protocol (%d): %s\n", iphead->protocol,
470 IP_PROTOCOL_number[iphead->protocol]);
471 else
472 printf ("Protocol (%d) not recognised\n", iphead->protocol);
473 printf ("\n");
474 }
475
476 int
check_packet(_32_bit ipaddr,const struct packetheader * p_header,const unsigned char * sp,char * file,char * file2,struct unwrap * info,char * detail,int MODE)477 check_packet (_32_bit ipaddr,
478 const struct packetheader *p_header,
479 const unsigned char *sp,
480 char *file,
481 char *file2,
482 struct unwrap *info,
483 char *detail,
484 int MODE)
485 /* MODE 0: -t MODE 1: -s */
486 /* MODE 2: -b */
487 {
488 unsigned char *so, *dest;
489 char wc_so[20], wc_dest[20];
490 struct IP_header iphead;
491 struct TCP_header tcphead;
492 struct ICMP_header icmphead;
493 struct UDP_header udphead;
494 int proto;
495 unsigned int prior;
496 char selected;
497 int i; /* Wildcard stuff */
498 unsigned char *str_IP;
499 unsigned int n_s; /* strlen short notation for wc bugfix */
500
501 proto = unwrap_packet (sp, info);
502 if(proto == NOT_SUPPORTED)
503 {
504 #ifdef DEBUG_ONSCREEN
505 printf("unwrap: NOT_SUPPORTED\n");
506 #endif
507 return DROP_PACKET;} /* no use in trying */
508 if(proto == NO_IP)
509 {
510 #ifdef DEBUG_ONSCREEN
511 printf("unwrap: NO_IP\n");
512 #endif
513 return DROP_PACKET;} /* no use in trying */
514 if(proto == NO_IP_4)
515 {
516 #ifdef DEBUG_ONSCREEN
517 printf("unwrap: NO_IP_4\n");
518 #endif
519 return DROP_PACKET;} /* no use in trying */
520 if(proto == CORRUPT_IP)
521 {
522 #ifdef DEBUG_ONSCREEN
523 printf("unwrap: CORRUPT_IP\n");
524 #endif
525 printf("Suspicious Packet detected... \n");
526 return DROP_PACKET;}
527
528 memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header));
529 so = (unsigned char *) &(iphead.source);
530 dest = (unsigned char *) &(iphead.destination);
531
532 if ( ((proto == TCP)||(proto==TCP_FRAG_HEAD)) && (PROTOCOLS & F_TCP))
533 {
534 #ifdef DEBUG_ONSCREEN
535 printf ("TCP Packet\n");
536 #endif
537 if((info->FRAG_nf==0)&&(proto!=TCP_FRAG_HEAD))
538 {
539 memcpy (&tcphead, (sp + PROTO_HEAD + info->IP_len),
540 sizeof (struct TCP_header));
541 memcpy (detail, &tcphead, sizeof (struct TCP_header));
542 }
543
544 if ((WILDCARD == 0) && (CFG_FILE == 0)) /* Selection criteria */
545 {
546 if (MODE == DEST && ipaddr != iphead.destination /* -t */
547 ||
548 MODE == SOURCE && ipaddr != iphead.source /* -s */
549 ||
550 MODE == BOTH && ipaddr != iphead.destination /* -b */
551 && ipaddr != iphead.source
552 )
553 return DONT_EXAMINE; /* Check destination/source IP */
554 }
555 else
556 {
557 if (WILDCARD != 0) /* Wildcards */
558 {
559 #ifdef DEBUG_ONSCREEN
560 printf ("WILDCARD\n");
561 #endif
562 sprintf (wc_so, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]);
563 sprintf (wc_dest, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]);
564 n_s = strlen (IP);
565 if (MODE == DEST && (strncmp (wc_dest, IP, n_s) != 0) /* -t */
566 ||
567 MODE == SOURCE && (strncmp (wc_so, IP, n_s) != 0) /* -s */
568 ||
569 MODE == BOTH && (strncmp (wc_dest, IP, n_s) != 0) /* -b */
570 && (strncmp (wc_so, IP, n_s) != 0)
571 )
572 return DONT_EXAMINE;
573 /* Check destination/source IP */
574 }
575 else
576 { /* We are using the config file (4*Check) */
577 prior = 0;
578 selected = 0;
579 sprintf (wc_so, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]);
580 sprintf (wc_dest, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]);
581 #ifdef DEBUG_ONSCREEN
582 if((info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD))
583 printf ("CONCERNING: %s %d - %s %d\n", wc_so, ntohs (tcphead.source), wc_dest, ntohs (tcphead.destination));
584 #endif
585 /* Highest prior last (backward+break for speed) */
586 for (i = (select_from_length - 1); i >= 0; i--)
587 {
588 if (prior > select_from_list[i].priority)
589 break;
590 str_IP = select_from_list[i].host;
591 #ifdef DEBUG_ONSCREEN
592 printf ("SF: %s %d Prior:%d\n", str_IP, select_from_list[i].port, select_from_list[i].priority);
593 #endif
594 /* tcphead is reserved anyway (even when fragmented) */
595 if ((select_from_list[i].port == 0) ||
596 (select_from_list[i].port == ntohs (tcphead.source)) ||
597 (info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD)
598 )
599 {
600 if (select_from_list[i].wildcard == 0)
601 { /* NO wildcard */
602 if (strcmp (wc_so, str_IP) == 0)
603 {
604 selected = 1;
605 prior = select_from_list[i].priority;
606 break;
607 }
608 }
609 else
610 { /* wildcard */
611 if (strncmp (wc_so, str_IP, strlen (str_IP)) == 0)
612 {
613 selected = 1;
614 prior = select_from_list[i].priority;
615 break;
616 }
617 }
618 if (str_IP[0] == 0)
619 {
620 selected = 1;
621 break;
622 };
623 }
624 }
625
626 for (i = (select_to_length - 1); i >= 0; i--)
627 {
628 if (prior > select_to_list[i].priority)
629 break;
630 str_IP = select_to_list[i].host;
631 #ifdef DEBUG_ONSCREEN
632 printf ("ST: %s %d Prior:%d\n", str_IP, select_to_list[i].port, select_to_list[i].priority);
633 #endif
634 if ((select_to_list[i].port == 0) ||
635 (select_to_list[i].port == ntohs (tcphead.destination))||
636 (info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD)
637 )
638 {
639 if (select_to_list[i].wildcard == 0)
640 { /* NO wildcard */
641 if (strcmp (wc_dest, str_IP) == 0)
642 {
643 selected = 1;
644 prior = select_to_list[i].priority;
645 break;
646 }
647 }
648 else
649 { /* wildcard */
650 if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0)
651 {
652 selected = 1;
653 prior = select_to_list[i].priority;
654 break;
655 }
656 }
657 if (str_IP[0] == 0)
658 {
659 selected = 1;
660 break;
661 };
662 }
663 }
664
665 for (i = (deselect_from_length - 1); i >= 0; i--)
666 {
667 if (prior > deselect_from_list[i].priority)
668 break;
669 str_IP = deselect_from_list[i].host;
670 #ifdef DEBUG_ONSCREEN
671 printf ("DF: %s %d Prior:%d\n", str_IP, deselect_from_list[i].port, deselect_from_list[i].priority);
672 #endif
673 if ((deselect_from_list[i].port == 0) ||
674 (deselect_from_list[i].port == ntohs (tcphead.source))||
675 (info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD)
676 )
677 {
678 if (deselect_from_list[i].wildcard == 0)
679 { /* NO wildcard */
680 if (strcmp (wc_so, str_IP) == 0)
681 {
682 selected = 0;
683 prior = deselect_from_list[i].priority;
684 break;
685 }
686 }
687 else
688 { /* wildcard */
689 if (strcmp (wc_so, str_IP) == 0)
690 {
691 selected = 0;
692 prior = deselect_from_list[i].priority;
693 break;
694 }
695 }
696 if (str_IP[0] == 0)
697 {
698 selected = 0;
699 break;
700 };
701
702 }
703 }
704
705 for (i = (deselect_to_length - 1); i >= 0; i--)
706 {
707 if (prior > deselect_to_list[i].priority)
708 break;
709 str_IP = deselect_to_list[i].host;
710 #ifdef DEBUG_ONSCREEN
711 printf ("DT: %s %d Prior:%d\n", str_IP, deselect_to_list[i].port, deselect_to_list[i].priority);
712 #endif
713 if ((deselect_to_list[i].port == 0) ||
714 (deselect_to_list[i].port == ntohs (tcphead.destination))||
715 (info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD)
716 )
717 {
718 if (deselect_to_list[i].wildcard == 0)
719 { /* NO wildcard */
720 if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0)
721 {
722 selected = 0;
723 prior = deselect_to_list[i].priority;
724 break;
725 }
726 }
727 else
728 { /* wildcard */
729 if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0)
730 {
731 selected = 0;
732 prior = deselect_to_list[i].priority;
733 break;
734 }
735 }
736 if (str_IP[0] == 0)
737 {
738 selected = 0;
739 break;
740 };
741
742 }
743 }
744
745 #ifdef DEBUG_ONSCREEN
746 printf ("Selected: %d\n", selected);
747 #endif
748 if (selected == 0)
749 return DONT_EXAMINE;
750
751 }
752 }
753
754 if( (info->FRAG_nf==0)&&(proto!=TCP_FRAG_HEAD) )
755 if( (MODE!=BOTH && DEST_PORT && ntohs (tcphead.destination)!=DEST_PORT)
756 ||
757 (MODE!=BOTH && SRC_PORT && ntohs (tcphead.source)!=SRC_PORT)
758 ||
759 (MODE==BOTH && SRC_PORT && ntohs (tcphead.source)!=SRC_PORT
760 && ntohs (tcphead.destination)!=SRC_PORT)
761 ) /* with BOTH SRC_PORT&DEST_PORT should be the same!! */
762 /* DEST/SRC do not depend on the SOURCE or DEST modes! */
763 return DONT_EXAMINE; /* Check dest. PORT */
764
765 #ifdef DEBUG_ONSCREEN
766 printf ("Packet accepted\n");
767 #endif
768
769
770 if( (info->FRAG_nf==0)&&(proto!=TCP_FRAG_HEAD) )
771 {
772 /* inet_ntoa gave wrong output sometimes */
773 sprintf (file, "%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
774 so[0], so[1], so[2], so[3],
775 (unsigned short) ntohs (tcphead.source),
776 dest[0], dest[1], dest[2], dest[3],
777 (unsigned short) ntohs (tcphead.destination));
778 sprintf (file2, "%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
779 dest[0], dest[1], dest[2], dest[3],
780 (unsigned short) ntohs (tcphead.destination),
781 so[0], so[1], so[2], so[3],
782 (unsigned short) ntohs (tcphead.source));
783 }
784 else
785 {
786 /* inet_ntoa gave wrong output sometimes */
787 sprintf (file, "%u.%u.%u.%u-%u.%u.%u.%u",
788 so[0], so[1], so[2], so[3],
789 dest[0], dest[1], dest[2], dest[3]);
790 sprintf (file2, "%u.%u.%u.%u-%u.%u.%u.%u",
791 dest[0], dest[1], dest[2], dest[3],
792 so[0], so[1], so[2], so[3]);
793 }
794
795 if(info->FRAG_nf!=0)
796 return TCP_EX_FRAG_NF;
797
798 if(proto==TCP_FRAG_HEAD)
799 return TCP_EX_FRAG_HEAD;
800
801 if ((ntohs(tcphead.offset_flag) & FIN) != 0) /* check for reset conn. */
802 return TCP_FINISH; /* packet is a FIN */
803
804 if ((ntohs(tcphead.offset_flag) & RST) != 0) /* check for reset conn. */
805 return TCP_FINISH;
806
807 /*
808 * Used to be for speed, '-x' needs all info, so this too!
809 * if (info->DATA_len == 0)
810 * return DONT_EXAMINE;
811 */
812
813 return TCP_EXAMINE; /* interprete packet */
814 };
815
816 /***** WARNING: Remove if later fragment handling is done *************/
817 if(info->FRAG_nf!=0)
818 {printf("Fragment Skipped...\n"); return DONT_EXAMINE; };
819
820
821 if ((proto == ICMP) && (PROTOCOLS & F_ICMP)) /* ICMP packet checking */
822 {
823 memcpy (&icmphead, (sp + PROTO_HEAD + info->IP_len),
824 sizeof (struct ICMP_header));
825 memcpy (detail, &icmphead, sizeof (struct ICMP_header));
826 sprintf (file, "%u.%u.%u.%u > %u.%u.%u.%u",
827 so[0], so[1], so[2], so[3],
828 dest[0], dest[1], dest[2], dest[3]);
829 return ICMP_EXAMINE;
830 };
831 if ((proto == UDP) && (PROTOCOLS & F_UDP)) /* UDP packet checking */
832 {
833 #ifdef DEBUG_ONSCREEN
834 printf ("UDP Packet\n");
835 #endif
836 memcpy (&udphead, (sp + PROTO_HEAD + info->IP_len),
837 sizeof (struct UDP_header));
838 memcpy (detail, &udphead, sizeof (struct UDP_header));
839
840 if ((WILDCARD == 0) && (CFG_FILE == 0)) /* Selection criteria */
841 {
842 if (MODE == DEST && ipaddr != iphead.destination /* -t */
843 ||
844 MODE == SOURCE && ipaddr != iphead.source /* -s */
845 ||
846 MODE == BOTH && ipaddr != iphead.destination /* -b */
847 && ipaddr != iphead.source
848 )
849 return DONT_EXAMINE; /* Check destination/source IP */
850 }
851 else
852 {
853 if (WILDCARD != 0) /* Wildcards */
854 {
855 sprintf (wc_so, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]);
856 sprintf (wc_dest, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]);
857 n_s = strlen (IP);
858 if (MODE == DEST && (strncmp (wc_dest, IP, n_s) != 0) /* -t */
859 ||
860 MODE == SOURCE && (strncmp (wc_so, IP, n_s) != 0) /* -s */
861 ||
862 MODE == BOTH && (strncmp (wc_dest, IP, n_s) != 0) /* -b */
863 && (strncmp (wc_so, IP, n_s) != 0)
864 )
865 return DONT_EXAMINE;
866 /* Check destination/source IP */
867 }
868 else
869 { /* We are using the config file (4*Check) */
870 prior = 0;
871 selected = 0;
872 sprintf (wc_so, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]);
873 sprintf (wc_dest, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]);
874 #ifdef DEBUG_ONSCREEN
875 printf ("CONCERNING: %s %d - %s %d\n", wc_so, ntohs (udphead.source), wc_dest, ntohs (udphead.destination));
876 #endif
877 /* Highest prior last (backward+break for speed) */
878 for (i = (select_from_length - 1); i >= 0; i--)
879 {
880 if (prior > select_from_list[i].priority)
881 break;
882 str_IP = select_from_list[i].host;
883 #ifdef DEBUG_ONSCREEN
884 printf ("SF: %s %d Prior:%d\n", str_IP, select_from_list[i].port, select_from_list[i].priority);
885 #endif
886 if ((select_from_list[i].port == 0) ||
887 (select_from_list[i].port == ntohs (udphead.source)))
888 {
889 if (select_from_list[i].wildcard == 0)
890 { /*
891 * NO wildcard
892 */
893 if (strcmp (wc_so, str_IP) == 0)
894 {
895 selected = 1;
896 prior = select_from_list[i].priority;
897 break;
898 }
899 }
900 else
901 { /*
902 * wildcard
903 */
904 if (strncmp (wc_so, str_IP, strlen (str_IP)) == 0)
905 {
906 selected = 1;
907 prior = select_from_list[i].priority;
908 break;
909 }
910 }
911 if (str_IP[0] == 0)
912 {
913 selected = 1;
914 break;
915 };
916 }
917 }
918
919 for (i = (select_to_length - 1); i >= 0; i--)
920 {
921 if (prior > select_to_list[i].priority)
922 break;
923 str_IP = select_to_list[i].host;
924 #ifdef DEBUG_ONSCREEN
925 printf ("ST: %s %d Prior:%d\n", str_IP, select_to_list[i].port, select_to_list[i].priority);
926 #endif
927 if ((select_to_list[i].port == 0) ||
928 (select_to_list[i].port == ntohs (udphead.destination)))
929 {
930 if (select_to_list[i].wildcard == 0)
931 { /*
932 * NO wildcard
933 */
934 if (strcmp (wc_dest, str_IP) == 0)
935 {
936 selected = 1;
937 prior = select_to_list[i].priority;
938 break;
939 }
940 }
941 else
942 { /*
943 * wildcard
944 */
945 if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0)
946 {
947 selected = 1;
948 prior = select_to_list[i].priority;
949 break;
950 }
951 }
952 if (str_IP[0] == 0)
953 {
954 selected = 1;
955 break;
956 };
957 }
958 }
959
960 for (i = (deselect_from_length - 1); i >= 0; i--)
961 {
962 if (prior > deselect_from_list[i].priority)
963 break;
964 str_IP = deselect_from_list[i].host;
965 #ifdef DEBUG_ONSCREEN
966 printf ("DF: %s %d Prior:%d\n", str_IP, deselect_from_list[i].port, deselect_from_list[i].priority);
967 #endif
968 if ((deselect_from_list[i].port == 0) ||
969 (deselect_from_list[i].port == ntohs (udphead.source)))
970 {
971 if (deselect_from_list[i].wildcard == 0)
972 { /* NO wildcard */
973 if (strcmp (wc_so, str_IP) == 0)
974 {
975 selected = 0;
976 prior = deselect_from_list[i].priority;
977 break;
978 }
979 }
980 else
981 { /* wildcard */
982 if (strcmp (wc_so, str_IP) == 0)
983 {
984 selected = 0;
985 prior = deselect_from_list[i].priority;
986 break;
987 }
988 }
989 if (str_IP[0] == 0)
990 {
991 selected = 0;
992 break;
993 };
994 }
995 }
996
997 for (i = (deselect_to_length - 1); i >= 0; i--)
998 {
999 if (prior > deselect_to_list[i].priority)
1000 break;
1001 str_IP = deselect_to_list[i].host;
1002 #ifdef DEBUG_ONSCREEN
1003 printf ("DT: %s %d Prior:%d\n", str_IP, deselect_to_list[i].port, deselect_to_list[i].priority);
1004 #endif
1005 if ((deselect_to_list[i].port == 0) ||
1006 (deselect_to_list[i].port == ntohs (udphead.destination)))
1007 {
1008 if (deselect_to_list[i].wildcard == 0)
1009 { /* NO wildcard */
1010 if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0)
1011 {
1012 selected = 0;
1013 prior = deselect_to_list[i].priority;
1014 break;
1015 }
1016 }
1017 else
1018 { /* wildcard */
1019 if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0)
1020 {
1021 selected = 0;
1022 prior = deselect_to_list[i].priority;
1023 break;
1024 }
1025 }
1026 if (str_IP[0] == 0)
1027 {
1028 selected = 0;
1029 break;
1030 };
1031 }
1032 }
1033
1034 #ifdef DEBUG_ONSCREEN
1035 printf ("Selected: %d\n", selected);
1036 #endif
1037 if (selected == 0)
1038 return DONT_EXAMINE;
1039
1040 }
1041 }
1042
1043 if( (MODE!=BOTH && DEST_PORT && ntohs (udphead.destination)!=DEST_PORT)
1044 ||
1045 (MODE!=BOTH && SRC_PORT && ntohs (udphead.source)!=SRC_PORT)
1046 ||
1047 (MODE==BOTH && SRC_PORT && ntohs (udphead.source)!=SRC_PORT
1048 && ntohs (udphead.destination)!=SRC_PORT)
1049 ) /* with BOTH SRC_PORT&DEST_PORT should be the same!! */
1050 /* DEST/SRC do not depend on the SOURCE or DEST modes! */
1051 return DONT_EXAMINE; /* Check dest. PORT */
1052
1053 /* inet_ntoa gave wrong output sometimes */
1054 sprintf (file, "%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
1055 so[0], so[1], so[2], so[3],
1056 (unsigned short) ntohs (udphead.source),
1057 dest[0], dest[1], dest[2], dest[3],
1058 (unsigned short) ntohs (udphead.destination));
1059 sprintf (file2, "%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
1060 dest[0], dest[1], dest[2], dest[3],
1061 (unsigned short) ntohs (udphead.destination),
1062 so[0], so[1], so[2], so[3],
1063 (unsigned short) ntohs (udphead.source));
1064 return UDP_EXAMINE; /* interprete packet */
1065 }
1066 return DONT_EXAMINE;
1067 }
1068
1069 /* Default Processing of packets */
1070 pcap_handler
packethandler(unsigned char * ipaddrpoint,const struct packetheader * p_header,const unsigned char * sp)1071 packethandler (unsigned char *ipaddrpoint,
1072 const struct packetheader * p_header,
1073 const unsigned char *sp)
1074 {
1075 char filename[50], filename2[50], header[SNAPLEN];
1076 FILE *f;
1077 struct file_info *dummy_pointer;
1078 unsigned char status = 0;
1079 char *help;
1080 int dummy, finish; /* look out it's signed */
1081 unsigned long datalen, position, total_length, i, n;
1082 _32_bit ipaddr;
1083 struct unwrap info;
1084 struct IP_header iphead;
1085 struct TCP_header tcphead;
1086 struct ICMP_header icmphead;
1087 struct IP_header iphead_icmp;
1088 struct UDP_header udphead;
1089 struct Plugin_data PL_d, PL_dex;
1090
1091 memcpy (&ipaddr, ipaddrpoint, sizeof (_32_bit));
1092
1093 finish = check_packet (ipaddr, p_header, sp, filename, filename2, &info, header, SNIFMODE);
1094
1095 if (finish == DROP_PACKET)
1096 return 0; /* Packet is broken */
1097
1098 if( (PROTOCOLS&F_IP)&&((PROTOCOLS&F_TCP)==0))
1099 memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header)),
1100 print_iphead (&iphead, 0);
1101
1102 if (finish == DONT_EXAMINE)
1103 return 0; /* Packet is not for us */
1104
1105 if(DUMPMODE==8) /* Recording */
1106 {
1107 pcap_dump((unsigned char *) dev_dump, p_header, sp);
1108 return 1;
1109 }
1110
1111 if((PROTOCOLS & F_IP)&&(PROTOCOLS & F_TCP)&&(finish<10))
1112 memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header)),
1113 print_iphead (&iphead, 0);
1114
1115
1116 #ifdef DEBUG_ONSCREEN
1117 printf ("Processing Packet (finish: %d)\n", finish);
1118 #endif
1119
1120 if ((finish < 10) || (finish >= 20 && finish < 30)) /* Start plugin */
1121 {
1122 if( (finish!=TCP_EX_FRAG_HEAD)&&(finish!=TCP_EX_FRAG_NF) )
1123 { /* no fragments to PLUGINS yet */
1124 /* fixing data structure */
1125 memcpy (&(PL_d.PL_info), &info, sizeof (struct unwrap));
1126 memcpy (&(PL_d.PL_iphead), (sp + PROTO_HEAD), sizeof (struct IP_header));
1127 memcpy (&(PL_d.PL_tcphead), (sp + PROTO_HEAD + info.IP_len), sizeof (struct TCP_header));
1128 memcpy (&(PL_d.PL_udphead), (sp + PROTO_HEAD + info.IP_len), sizeof (struct UDP_header));
1129 if (PL_d.PL_iphead.protocol == TCP)
1130 memcpy (PL_d.PL_data, (sp + PROTO_HEAD + info.IP_len + info.TCP_len), info.DATA_len);
1131 if (PL_d.PL_iphead.protocol == UDP)
1132 memcpy (PL_d.PL_data, (sp + PROTO_HEAD + info.IP_len + info.UDP_len), info.DATA_len);
1133 memcpy (PL_d.PL_packet, (sp + PROTO_HEAD),
1134 info.IP_len + info.TCP_len + info.UDP_len + info.DATA_len);
1135
1136 /* starting all plugins */
1137 for (i = 0; i < 10; i++)
1138 if (Plugin_Active[i] == 1)
1139 {
1140 memcpy (&PL_dex, &PL_d, sizeof (struct Plugin_data));
1141 start_plugin (i, &PL_dex);
1142 }
1143 }
1144 }
1145
1146 if ((DUMPMODE & 32) && (finish < 10)) /* extended info TCP only */
1147 {
1148 if( (finish!=TCP_EX_FRAG_HEAD)&&(finish!=TCP_EX_FRAG_NF) )
1149 {
1150 memcpy (&tcphead, header, sizeof (struct TCP_header));
1151 dummy = ntohs (tcphead.offset_flag);
1152 printf ("\n");
1153 printf ("TCP Packet ID (from_IP.port-to_IP.port): %s\n", filename);
1154 printf (" SEQ (hex): %lX ", ntohl (tcphead.seq_nr));
1155 if (dummy & ACK)
1156 printf ("ACK (hex): %lX\n", ntohl (tcphead.ACK_nr));
1157 printf (" FLAGS: %c%c%c%c%c%c",
1158 (dummy & URG) ? 'U' : '-', (dummy & ACK) ? 'A' : '-',
1159 (dummy & PSH) ? 'P' : '-', (dummy & RST) ? 'R' : '-',
1160 (dummy & SYN) ? 'S' : '-', (dummy & FIN) ? 'F' : '-');
1161 if (dummy & ACK)
1162 printf (" Window: %X\n", ntohs (tcphead.window));
1163 else
1164 printf ("\n");
1165 }
1166 };
1167
1168 if ((finish < 10) && (LOGPARAM == 0)) /* TCP packet */
1169 /* I didn't use flags for later extention, and they */
1170 /* don't come in pairs anyhow */
1171 /* use return instead of else {if}, for later extention */
1172 {
1173 if( (finish!=TCP_EX_FRAG_HEAD)&&(finish!=TCP_EX_FRAG_NF) )
1174 memcpy (&tcphead, header, sizeof (struct TCP_header));
1175
1176 switch (DUMPMODE & 199) /* without bit 3,4,5 (8,16,32) */
1177 {
1178 case 0: /* LOG mode */
1179 if( (finish==TCP_EX_FRAG_HEAD)||(finish==TCP_EX_FRAG_NF) )
1180 break; /* no FRAG handling in log mode yet */
1181 status = 0;
1182 dummy_pointer = search_dynam (filename, TCP);
1183 if (dummy_pointer != NULL)
1184 status = 1;
1185 /* make a new entry unless it's reset */
1186 if (status == 0)
1187 {
1188 if (finish == TCP_FINISH)
1189 return 1;
1190 /* there was never data transmitted */
1191 /* seq_nr & datalen not important here yet */
1192 if ((dummy_pointer = add_dynam (filename, TCP, 1, 0, 0)) == NULL)
1193 return 1;
1194 }
1195 f = dummy_pointer->f;
1196
1197 if (dummy_pointer->bytes <= SNIFLEN)
1198 {
1199 const unsigned char *data=
1200 sp + PROTO_HEAD + info.IP_len + info.TCP_len;
1201 if (SNIFLEN != 0)
1202 dummy_pointer->bytes += info.DATA_len;
1203 /* last packet is written */
1204 /* don't care about length */
1205 if (ASC == 0)
1206 {
1207 for (i = 0; i < info.DATA_len; i++)
1208 fprintf (f, "%c", data[i]);
1209 }
1210 else
1211 {
1212 for (i = 0; i < info.DATA_len; i++)
1213 fprintf (f, "%c", isprint (data[i]) ? data[i] : non_printable);
1214 };
1215 fflush (f); /* write all */
1216 }
1217 if (finish == TCP_FINISH) /* let's reset the connection */
1218 delete_dynam (filename, TCP, 1);
1219 break;
1220
1221 case 1: /* DUMP mode */
1222 case 2:
1223 case 3:
1224 memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header));
1225 printf ("Packet ID (from_IP.port-to_IP.port): %s\n", filename);
1226 total_length = info.IP_len + info.TCP_len + info.DATA_len;
1227 if(info.FRAG_f!=0)
1228 printf("The following packet is an IP Fragment (first/ID: %0X)...\n",
1229 ntohs(iphead.ID));
1230 if( (finish==TCP_EX_FRAG_HEAD)||(finish==TCP_EX_FRAG_NF) )
1231 {
1232 total_length = info.IP_len + info.DATA_len;
1233 if(finish==TCP_EX_FRAG_HEAD)
1234 printf("WARNING: Fragmented TCP header... suspicious... (ID: %0X) \n",
1235 ntohs(iphead.ID));
1236 if(finish==TCP_EX_FRAG_NF)
1237 printf("The following packet is a continued IP Fragment (ID: %0X)...\n",
1238 ntohs(iphead.ID));
1239 };
1240 n = 0;
1241 for (i = 0; i < total_length; i++)
1242 {
1243 unsigned char c = sp[PROTO_HEAD + i];
1244 if (n > 75)
1245 n = 0, printf ("\n");
1246 if (DUMPMODE & 1)
1247 n += printf (" %02X", c);
1248 if (DUMPMODE & 2)
1249 n += printf (" %c", isprint (c) ? c : '.');
1250 }
1251 printf ("\n\n");
1252 break;
1253 case 128:
1254 break; /* NO LOGGING MODE */
1255 default:
1256 printf ("\nYou mixed incompatible options!\n");
1257 exit (1);
1258 }
1259 return 1;
1260 }
1261
1262 if ((finish < 10) && (LOGPARAM != 0)) /* TCP packet - logfile */
1263 /* This mode will grow, so I just copied the other if() */
1264 /* instead of adding a dumpmode, I think this will keep */
1265 /* things more simpel. Also I use the smart dynam */
1266 /* managment of connections */
1267 {
1268 if( (finish!=TCP_EX_FRAG_HEAD)&&(finish!=TCP_EX_FRAG_NF) )
1269 { /* no FRAG handling in logfile mode yet */
1270 #include "sn_analyse.c" /* dirty, but it got too confusing */
1271 }
1272 }
1273
1274 if (finish < 20) /* ICMP packet */
1275 {
1276 memcpy (&icmphead, header, sizeof (struct ICMP_header));
1277 memcpy (&iphead_icmp,
1278 (sp + PROTO_HEAD + info.IP_len + ICMP_HEADLENGTH + 4),
1279 sizeof (struct IP_header));
1280 printf ("ICMP message id: %s\n", filename);
1281 printf (" ICMP type: ");
1282 switch (icmphead.type)
1283 {
1284 case 0:
1285 printf ("%s\n", ICMP_TYPE_0);
1286 break;
1287 case 3:
1288 printf ("%s\n", ICMP_TYPE_3);
1289 printf (" Error: %s\n",
1290 ICMP_type_3_code[icmphead.code]);
1291 print_iphead (&iphead_icmp, 1);
1292 break;
1293 case 4:
1294 printf ("%s\n", ICMP_TYPE_4);
1295 print_iphead (&iphead_icmp, 1);
1296 break;
1297 case 5:
1298 printf ("%s\n", ICMP_TYPE_5);
1299 printf (" Error: %s\n",
1300 ICMP_type_5_code[icmphead.code]);
1301 print_iphead (&iphead_icmp, 1);
1302 break;
1303 case 8:
1304 printf ("%s\n", ICMP_TYPE_8);
1305 break;
1306 case 11:
1307 printf ("%s\n", ICMP_TYPE_11);
1308 printf (" Error: %s\n",
1309 ICMP_type_11_code[icmphead.code]);
1310 print_iphead (&iphead_icmp, 1);
1311 break;
1312 case 12:
1313 printf ("%s\n", ICMP_TYPE_12);
1314 print_iphead (&iphead_icmp, 1);
1315 break;
1316 case 13:
1317 printf ("%s\n", ICMP_TYPE_13);
1318 break;
1319 case 14:
1320 printf ("%s\n", ICMP_TYPE_14);
1321 break;
1322 case 15:
1323 printf ("%s\n", ICMP_TYPE_15);
1324 break;
1325 case 16:
1326 printf ("%s\n", ICMP_TYPE_16);
1327 break;
1328 case 17:
1329 printf ("%s\n", ICMP_TYPE_17);
1330 break;
1331 case 18:
1332 printf ("%s\n", ICMP_TYPE_18);
1333 break;
1334 default:
1335 printf ("Unknown ICMP type!\n");
1336 break;
1337 }
1338 printf ("\n");
1339 return 1;
1340 }
1341 if (finish < 30) /* nothing yet */
1342 {
1343 memcpy (&udphead, header, sizeof (struct UDP_header));
1344 switch (DUMPMODE & 223)
1345 {
1346 case 0:
1347 break;
1348 case 1: /* DUMP mode */
1349 case 2:
1350 case 3:
1351 printf ("UDP Packet ID (from_IP.port-to_IP.port): %s\n", filename);
1352 total_length = info.IP_len + info.UDP_len + info.DATA_len;
1353 n = 0;
1354 for (i = 0; i < total_length; i++)
1355 {
1356 unsigned char c = sp[PROTO_HEAD + i];
1357 if (n > 75)
1358 n = 0, printf ("\n");
1359 if (DUMPMODE & 1)
1360 n += printf (" %02X", c);
1361 if (DUMPMODE & 2)
1362 n += printf (" %c", isprint (c) ? c : '.');
1363 }
1364 printf ("\n\n");
1365 break;
1366 case 128:
1367 break; /* NO LOGGING MODE */
1368 default:
1369 printf ("\nImpossible error! Sniffer Heartattack!\n");
1370 exit (0);
1371 }
1372 return 1;
1373 }
1374 }
1375
1376
1377 #ifdef INCLUDE_INTERFACE /* Interactive packethandling */
1378 int
check_mask(const struct packetheader * p_header,const unsigned char * sp,char * conn_name,char * conn_name2,char * desc_string,struct unwrap * info)1379 check_mask (const struct packetheader *p_header,
1380 const unsigned char *sp,
1381 char *conn_name, char *conn_name2, char *desc_string,
1382 struct unwrap *info)
1383 /* return -1 : packet not for us */
1384 /* else finish value */
1385 {
1386 char helpstr1[20], helpstr2[20];
1387 unsigned char *so, *dest;
1388 struct IP_header iphead;
1389 struct TCP_header tcphead;
1390 int proto, i,j;
1391
1392 proto = unwrap_packet (sp, info);
1393 /* Interface, no output allowed to stdout */
1394 if(proto == NOT_SUPPORTED)
1395 return DROP_PACKET; /* no use in trying */
1396 if (proto == NO_IP)
1397 return DROP_PACKET; /* no use in trying */
1398 if (proto == NO_IP_4)
1399 return DROP_PACKET; /* no use in trying */
1400 if(proto == CORRUPT_IP)
1401 return DROP_PACKET; /* no use in trying */
1402
1403 if((info->FRAG_nf!=0)||(info->FRAG_f!=0))
1404 {return DONT_EXAMINE; };
1405 /* No fragments studied at all */
1406
1407
1408 (*IP_nr_of_packets)++;
1409 if (proto == ICMP)
1410 {
1411 (*ICMP_nr_of_packets)++;
1412 return DONT_EXAMINE;
1413 }
1414 if (proto == UDP)
1415 {
1416 (*UDP_nr_of_packets)++;
1417 (*UDP_bytes_in_packets) += (info->UDP_len + info->DATA_len + info->IP_len);
1418 return DONT_EXAMINE;
1419 }
1420 if (proto != TCP)
1421 return DONT_EXAMINE;
1422 /* Packet info */
1423 (*TCP_nr_of_packets)++;
1424 (*TCP_bytes_in_packets) += (info->TCP_len + info->DATA_len + info->IP_len);
1425 /* Not a TCP packet */
1426 memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header));
1427 memcpy (&tcphead, (sp + PROTO_HEAD + info->IP_len), sizeof (struct TCP_header));
1428
1429 if (mask->source_ip != 0 && iphead.source != mask->source_ip)
1430 return DONT_EXAMINE;
1431 if (mask->destination_ip != 0 && iphead.destination != mask->destination_ip)
1432 return DONT_EXAMINE;
1433 if (mask->destination_port && ntohs (tcphead.destination) != mask->destination_port)
1434 return DONT_EXAMINE;
1435 if (mask->source_port && ntohs (tcphead.source) != mask->source_port)
1436 return DONT_EXAMINE;
1437
1438 /* inet_ntoa gave wrong output sometimes */
1439 so = (unsigned char *) &(iphead.source);
1440 dest = (unsigned char *) &(iphead.destination);
1441
1442 sprintf (helpstr1, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]);
1443 sprintf (helpstr2, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]);
1444
1445 sprintf (conn_name, "%16s %5u -> %16s %5u",
1446 helpstr1,
1447 ntohs (tcphead.source),
1448 helpstr2,
1449 ntohs (tcphead.destination));
1450 sprintf (conn_name2, "%16s %5u -> %16s %5u",
1451 helpstr2,
1452 ntohs (tcphead.destination),
1453 helpstr1,
1454 ntohs (tcphead.source));
1455
1456 if(INTERACTIVE_EXTEND==1)
1457 {
1458 #include "sn_conn_desc.c" /* Some detection */
1459 }
1460
1461 if ((ntohs (tcphead.offset_flag) & FIN) != 0) /* check for reset conn. */
1462 return TCP_FINISH; /* packet is a FIN */
1463 if ((ntohs (tcphead.offset_flag) & RST) != 0) /* check for reset conn. */
1464 return TCP_FINISH; /* packet is a RST */
1465 if (info->DATA_len == 0)
1466 return DONT_EXAMINE; /*packet not for us */
1467 return TCP_EXAMINE; /* interprete packet */
1468 }
1469
1470 pcap_handler
interactive_packethandler(char * dummy,const struct packetheader * p_header,const unsigned char * sp)1471 interactive_packethandler (char *dummy,
1472 const struct packetheader * p_header,
1473 const unsigned char *sp)
1474 {
1475 char conn_name[CONN_NAMELEN], conn_name2[CONN_NAMELEN];
1476 char desc_string[DESC_BYTES];
1477 int finish; /* look out it's signed */
1478 struct unwrap info;
1479
1480 if(INTERACTIVE_EXTEND==1)
1481 strcpy (desc_string, "Unknown");
1482
1483 finish = check_mask (p_header, sp, conn_name, conn_name2, desc_string, &info);
1484 if (finish == DROP_PACKET)
1485 return 0; /* Packet is broken */
1486 if (finish == DONT_EXAMINE)
1487 return 0; /* Packet is not for us */
1488
1489 if (finish != TCP_FINISH) /* finish: already logged, or to short to add */
1490 add_itemlist (running_connections, conn_name, desc_string);
1491 if (strcmp (log_conn->log_enter, conn_name) == 0)
1492 {
1493 const unsigned char *data = sp + PROTO_HEAD + info.IP_len + info.TCP_len;
1494 if (*DATAlength + info.DATA_len < LENGTH_OF_INTERPROC_DATA)
1495 {
1496 memcpy ((connection_data + *DATAlength), data, info.DATA_len);
1497 *DATAlength += info.DATA_len;
1498 }
1499 }
1500 if (finish == TCP_FINISH)
1501 {
1502 del_itemlist (running_connections, conn_name);
1503 del_itemlist (running_connections, conn_name2);
1504 }
1505 kill (getppid (), SIGUSR1);
1506 }
1507 #endif
1508
1509
1510
main(int argc,char * argv[])1511 int main (int argc, char *argv[])
1512 {
1513 char *dev, forced_dev[20], buffer[SNAPLEN];
1514 char ebuf[PCAP_ERRBUF_SIZE];
1515 unsigned char *DUMPfile; /* file used for packed logging */
1516 int c, i;
1517 unsigned long memsize;
1518 _32_bit ipaddr;
1519 int flag = 0, doboth = 0, FORCE_DEV = 0, SUPPORTED = 0;
1520 extern char *optarg;
1521
1522 signal (SIGINT, my_exit); /* graceful termination in different ways */
1523 signal (SIGHUP, my_exit);
1524 signal (SIGTERM, my_exit);
1525
1526 SNIFLEN = 300; /* Set defaults */
1527 DEST_PORT = SRC_PORT = 0; /* dest & source Port */
1528 INTERACTIVE_EXTEND=SNIFMODE = DUMPMODE = PROTOCOLS = ASC = WILDCARD =
1529 CFG_FILE = NO_CHKSUM = 0;
1530 LOGPARAM = 0;
1531 Logfile[0] = 0;
1532 logging_device = NULL;
1533 IP[0]=0;
1534 for (i = 0; i < 10; i++)
1535 Plugin_Active[i] = 0; /* Active plugins */
1536
1537 #ifdef DEBUG
1538 if ((debug_dev = fopen (DEBUG_DEVICE, "a")) < 0)
1539 {
1540 printf ("Couldn't open DEBUG device!\n");
1541 exit (0);
1542 }
1543 else
1544 {
1545 fprintf (debug_dev, "\n\nDEVICE OPENED FOR SNIFFIT DEBUGGING\n\n");
1546 exit_func (close_debug_device);
1547 }
1548 #endif
1549
1550 #ifdef INCLUDE_INTERFACE
1551 while ((c = getopt (argc, argv, "D:A:P:iIdp:l:xabt:s:F:c:nvL:M:Nr:R:")) != -1)
1552 {
1553 #else
1554 while ((c = getopt (argc, argv, "A:P:dp:l:xabt:s:F:c:nvL:M:Nr:R:")) != -1)
1555 {
1556 #endif
1557 /* Argument treating */
1558 switch (c)
1559 {
1560 case 'v':
1561 printf ("Sniffit Version %s - Copyright 1996-98 Brecht Claerhout\n", VERSION);
1562 #ifdef __DATE__
1563 printf ("Binary build %s %s\n", __DATE__, __TIME__);
1564 #endif
1565 quit (argv[0]);
1566 break;
1567 case 'd':
1568 if(DUMPMODE&8) quit(argv[0]);
1569 DUMPMODE |= 1;
1570 break;
1571 case 'a':
1572 if(DUMPMODE&8) quit(argv[0]);
1573 DUMPMODE |= 2;
1574 break;
1575 case 'R': /* recording (not mixable) */
1576 if(DUMPMODE) quit(argv[0]);
1577 DUMPMODE=8;
1578 DUMPfile=(unsigned char *)optarg;
1579 break;
1580 case 'r':
1581 if(DUMPMODE&8) quit(argv[0]);
1582 DUMPMODE|=16; /* reading (mixable) */
1583 DUMPfile=(unsigned char *)optarg;
1584 break;
1585 case 'x':
1586 if(DUMPMODE&8) quit(argv[0]);
1587 DUMPMODE |= 32;
1588 break;
1589 case 'N':
1590 if(DUMPMODE&8) quit(argv[0]);
1591 DUMPMODE |= 128;
1592 break;
1593 case 'p':
1594 if(DEST_PORT!=0)
1595 printf("Conflicting ports... (using %d as destination port)\n",
1596 atoi(optarg));
1597 DEST_PORT = atoi(optarg);
1598 break;
1599 case 'l':
1600 SNIFLEN = atol (optarg);
1601 break;
1602 case 'L':
1603 LOGPARAM |= LOGPARAM_LOG_ON;
1604 strlower (optarg);
1605 if (strstr (optarg, "raw"))
1606 LOGPARAM |= LOGPARAM_RAW;
1607 if (strstr (optarg, "norm"))
1608 LOGPARAM |= LOGPARAM_NORM;
1609 if (strstr (optarg, "telnet"))
1610 LOGPARAM |= LOGPARAM_TELNET;
1611 if (strstr (optarg, "ftp"))
1612 LOGPARAM |= LOGPARAM_FTP;
1613 if (strstr (optarg, "mail"))
1614 LOGPARAM |= LOGPARAM_MAIL;
1615 break;
1616 case 'b':
1617 doboth = 1;
1618 break;
1619 case 'A':
1620 ASC = 1;
1621 non_printable = *optarg;
1622 break;
1623 case 'D':
1624 logging_device = optarg;
1625 break;
1626 case 'P':
1627 strlower (optarg);
1628 if (strstr (optarg, "tcp"))
1629 PROTOCOLS |= F_TCP;
1630 if (strstr (optarg, "icmp"))
1631 PROTOCOLS |= F_ICMP;
1632 if (strstr (optarg, "udp"))
1633 PROTOCOLS |= F_UDP;
1634 if (strstr (optarg, "ip"))
1635 PROTOCOLS |= F_IP;
1636 break;
1637 case 's':
1638 {
1639 char hlp[300], *hlp2;
1640
1641 flag++;
1642 SNIFMODE = SOURCE;
1643 hlp[299]=0;
1644 strncpy(hlp,optarg,299);
1645 hlp2=(char *)strtok(hlp,":");
1646 IP[255]=0;
1647 strncpy(IP,hlp2,255);
1648 if((hlp2=(char *)strtok(NULL,":"))!=NULL)
1649 SRC_PORT = atoi(hlp2);
1650 break;
1651 }
1652 case 't':
1653 {
1654 char hlp[300], *hlp2;
1655
1656 flag++;
1657 SNIFMODE = DEST;
1658 hlp[299]=0;
1659 strncpy(hlp,optarg,299);
1660 hlp2=(char *)strtok(hlp,":");
1661 IP[255]=0;
1662 strncpy(IP,hlp2,255);
1663 if((hlp2=(char *)strtok(NULL,":"))!=NULL)
1664 {
1665 if(DEST_PORT!=0)
1666 printf("Conflicting ports... (using %d as destination port)\n",
1667 atoi(hlp2));
1668 DEST_PORT = atoi(hlp2);
1669 }
1670 break;
1671 }
1672 case 'i':
1673 flag++;
1674 SNIFMODE = INTERACTIVE;
1675 INTERACTIVE_EXTEND=0;
1676 break;
1677 case 'I':
1678 flag++;
1679 SNIFMODE = INTERACTIVE;
1680 INTERACTIVE_EXTEND=1;
1681 break;
1682 case 'n':
1683 NO_CHKSUM = 1;
1684 break;
1685 case 'M':
1686 if ((atoi (optarg) >= 0) && (atoi (optarg) <= 9))
1687 Plugin_Active[atoi (optarg)] = 1;
1688 break;
1689 case 'F':
1690 strcpy (forced_dev, optarg);
1691 FORCE_DEV = 1;
1692 break;
1693 case 'c':
1694 flag++;
1695 read_cfg_file (optarg);
1696 #ifdef DEBUG_ONSCREEN
1697 printf ("FINISHED INTERPRETING\n");
1698 printf ("sf:%d st:%d df:%d dt:%d\n", select_from_length, select_to_length, deselect_from_length, deselect_to_length);
1699 #endif
1700 CFG_FILE = 1;
1701 break;
1702 case '?':
1703 quit(argv[0]);
1704 break;
1705 default:
1706 break;
1707 }
1708 }
1709
1710 #ifdef ALLOW_SUID
1711 if ((getuid () != 0) && (geteuid () != 0))
1712 printf ("You should be root to run this program!\n"), exit (1);
1713 #else
1714 if (getuid () != 0)
1715 printf ("You should be root to run this program!\n"), exit (1);
1716 #endif
1717
1718 if (flag != 1)
1719 quit (argv[0]);
1720 if ((LOGPARAM != 0) && (CFG_FILE == 0))
1721 quit (argv[0]);
1722
1723 if (LOGPARAM != 0)
1724 open_logfile ();
1725 if (PROTOCOLS == 0)
1726 PROTOCOLS |= F_TCP;
1727 if (doboth)
1728 {
1729 SNIFMODE = BOTH;
1730 if( DEST_PORT&&SRC_PORT&&(DEST_PORT!=SRC_PORT) )
1731 printf("Conflicting ports... (result might not be what you want!)\n");
1732 if(DEST_PORT==0) DEST_PORT=SRC_PORT;
1733 /* ports should be the same for BOTH */
1734 else SRC_PORT=DEST_PORT;
1735 }
1736 if ((SNIFMODE != INTERACTIVE) && (CFG_FILE == 0))
1737 {
1738 /* if(index(IP,'@')) For SunOS */
1739 if (strchr (IP, '@'))
1740 {
1741 printf ("Wildcard detected, IP nr. not checked...\n");
1742 WILDCARD = 1;
1743 /* strcpy(index(IP,'@'),"\0"); */
1744 strcpy (strchr (IP, '@'), "\0");
1745 }
1746 else
1747 {
1748 ipaddr = getaddrbyname (IP);
1749 if (ipaddr == 0)
1750 printf ("Non existing host!\n"), exit (1);
1751 }
1752 }
1753 reset_all (); /* just to be sure */
1754
1755 if(DUMPMODE&16) /* read from a file */
1756 {
1757 if(FORCE_DEV==0) quit(argv[0]);
1758 if((dev_desc=pcap_open_offline(DUMPfile,ebuf))==NULL)
1759 fprintf (stderr,"%s\n",ebuf), exit (0);
1760 } /* real device */
1761
1762 if (FORCE_DEV != 0) /* 0.3.6 core dump fix */
1763 {
1764 if((dev=malloc(strlen(forced_dev)+1))==NULL)
1765 fprintf(stderr,"Couldn't allocate memory...\n");
1766 strcpy (dev, forced_dev);
1767 printf ("Forcing device to %s (user requested)...\n", dev);
1768 printf ("Make sure you have read the docs carefully.\n");
1769 PROTO_HEAD = FORCED_HEAD_LENGTH;
1770 }
1771 else
1772 {
1773 if((dev = pcap_lookupdev (ebuf)) == NULL)
1774 fprintf (stderr,"%s\n",ebuf), exit (1);
1775 }
1776
1777 for (i = 0; i < NETDEV_NR; i++)
1778 if (strstr (dev, NETDEV[i])) /* For expansion */
1779 {
1780 PROTO_HEAD = HEADSIZE[i];
1781 printf ("Supported Network device found. (%s)\n", dev);
1782 SUPPORTED = 1;
1783 break;
1784 }
1785
1786 if ((SUPPORTED == 0) && (FORCE_DEV == 0)) /* not supported & not forced */
1787 {
1788 printf ("Network device found... BUT not known by Sniffit, use '-F <netw device>' option!\n");
1789 printf ("Read the README.FIRST on how to force network devices.\n");
1790 exit (1);
1791 }
1792
1793 if(!(DUMPMODE&16))
1794 if ((dev_desc = pcap_open_live (dev, SNAPLEN, 1, MSDELAY, ebuf)) == NULL)
1795 fprintf (stderr,"%s\n",ebuf), exit (0);
1796 else
1797 exit_func(close_pcapdev);
1798 if(FORCE_DEV!=0) {free(dev);} /* no longer needed */
1799
1800 #ifdef PLUGIN0_INIT()
1801 if (Plugin_Active[0] == 1)
1802 PLUGIN0_INIT ();
1803 #endif
1804 #ifdef PLUGIN1_INIT()
1805 if (Plugin_Active[1] == 1)
1806 PLUGIN1_INIT ();
1807 #endif
1808 #ifdef PLUGIN2_INIT()
1809 if (Plugin_Active[2] == 1)
1810 PLUGIN2_INIT ();
1811 #endif
1812 #ifdef PLUGIN3_INIT()
1813 if (Plugin_Active[3] == 1)
1814 PLUGIN3_INIT ();
1815 #endif
1816 #ifdef PLUGIN4_INIT()
1817 if (Plugin_Active[4] == 1)
1818 PLUGIN4_INIT ();
1819 #endif
1820 #ifdef PLUGIN5_INIT()
1821 if (Plugin_Active[5] == 1)
1822 PLUGIN5_INIT ();
1823 #endif
1824 #ifdef PLUGIN6_INIT()
1825 if (Plugin_Active[6] == 1)
1826 PLUGIN6_INIT ();
1827 #endif
1828 #ifdef PLUGIN7_INIT()
1829 if (Plugin_Active[7] == 1)
1830 PLUGIN7_INIT ();
1831 #endif
1832 #ifdef PLUGIN8_INIT()
1833 if (Plugin_Active[8] == 1)
1834 PLUGIN8_INIT ();
1835 #endif
1836 #ifdef PLUGIN9_INIT()
1837 if (Plugin_Active[9] == 1)
1838 PLUGIN9_INIT ();
1839 #endif
1840
1841 #ifdef INCLUDE_INTERFACE
1842 if (SNIFMODE == INTERACTIVE)
1843 {
1844 memsize = sizeof (int) + sizeof (int) + LENGTH_OF_INTERPROC_DATA +
1845 sizeof (int) + sizeof (struct snif_mask) +
1846 sizeof (struct shared_logged_conn) +
1847 (CONNECTION_CAPACITY * sizeof (struct shared_conn_data)) +
1848 sizeof (int) +
1849 sizeof (unsigned long) + sizeof (int) + sizeof (int) + sizeof (unsigned long) +
1850 sizeof (int) + sizeof (int);
1851 memory_id = shmget (0, memsize, 0700);
1852 if (memory_id < 0)
1853 {
1854 perror ("Interactive Sniffer Heartattack (No Shared mem avail!)");
1855 exit (0);
1856 }
1857 exit_func (mem_exit);
1858 if ((SHARED = shmat (memory_id, 0, SHM_RND)) == NULL)
1859 {
1860 perror ("Interactive Sniffer Heartattack (Wow something is wrong here)");
1861 exit (0);
1862 };
1863 printf ("Entering Shared memory at %p\n", SHARED);
1864 printf ("Shared %d\n", memsize);
1865
1866 timing = SHARED; /* set all pointers */
1867 DATAlength = timing + sizeof (int);
1868 connection_data = DATAlength + sizeof (int);
1869 LISTlength = connection_data + LENGTH_OF_INTERPROC_DATA;
1870 mask = LISTlength + sizeof (int);
1871 logged_connections = mask + sizeof (struct snif_mask);
1872 log_conn = (struct shared_logged_conn *) logged_connections;
1873 running_connections = logged_connections + sizeof (struct shared_logged_conn);
1874 TCP_nr_of_packets = running_connections + (sizeof (struct shared_conn_data) * CONNECTION_CAPACITY);
1875 TCP_bytes_in_packets = TCP_nr_of_packets + sizeof (int);
1876 ICMP_nr_of_packets = TCP_bytes_in_packets + sizeof (unsigned long);
1877 UDP_nr_of_packets = ICMP_nr_of_packets + sizeof (int);
1878 UDP_bytes_in_packets = UDP_nr_of_packets + sizeof (int);
1879 IP_nr_of_packets = UDP_bytes_in_packets + sizeof (unsigned long);
1880 DESC_LEN = IP_nr_of_packets + sizeof (int);
1881 clear_shared_mem (0);
1882
1883 *DESC_LEN = 10; /* not necessary, but for security (eliminate very unlikely races) */
1884
1885 if ((Pid = fork ()) < 0)
1886 {
1887 perror ("Interactive Sniffer Heartattack (Couldn't fork)");
1888 exit (0);
1889 };
1890 if (Pid == 0)
1891 {
1892 sleep (4);
1893 if (pcap_loop (dev_desc, CNT,
1894 interactive_packethandler, NULL) < 0)
1895 printf ("Capturing Packets Failed\n"), exit (0);
1896 }
1897 else
1898 {
1899 exit_func (child_exit);
1900 signal (SIGCHLD, SIG_IGN);
1901 if (logging_device != NULL)
1902 {
1903 if (stat (logging_device, &log_dev_stat) < 0)
1904 perror ("\'-D\' option error"), exit (0);
1905 if ((log_dev_stream = fopen (logging_device, "a"))
1906 == NULL)
1907 printf ("Couldn't open device for logging output\n"), exit (0);
1908 }
1909 run_interface ();
1910 }
1911 }
1912 else
1913 {
1914 #endif
1915 if (CFG_FILE == 0)
1916 printf ("Sniffit.%s is up and running.... (%s)\n\n", VERSION, IP);
1917 else
1918 printf ("Sniffit.%s is up and running.... (Config File Used)\n\n", VERSION);
1919 if(DUMPMODE&8)
1920 {
1921 if((dev_dump=pcap_dump_open(dev_desc, DUMPfile))==NULL)
1922 fprintf (stderr, "Capturing Packets Failed\n"), exit (0);
1923 exit_func(close_dumpfile);
1924 }
1925
1926
1927 switch (pcap_loop (dev_desc, CNT, packethandler, (unsigned char *) &ipaddr))
1928 {
1929 case -1:
1930 fprintf (stderr, "Capturing Packets Failed\n"), exit (0); break;
1931 case 0:
1932 exit(0);
1933 default:
1934 break;
1935 }
1936 #ifdef INCLUDE_INTERFACE
1937 }
1938 #endif
1939 }
1940