/* Sniffit main program file */ /* - by : Brecht Claerhout */ #include "sn_config.h" /* Config header file */ #include #include #include #include /* #include */ #include #include #include #include #include #include /* #include */ /* for inet_addr() */ #ifdef INCLUDE_INTERFACE #include #include #endif #include "pcap.h" /************************ Own includes *************************************/ #include "sn_defines.h" /* Various defines */ #include "sn_structs.h" /* All structures */ #include "sn_global.h" /* some global defs */ #include "sn_data.h" /* data defs */ #include "sn_packets.h" /* My own packet structs */ #include "sn_logfile.h" #include "sn_cfgfile.h" /* Config file handling */ #include "sn_resolv.h" /* Host resolution */ #include "sn_plugins.h" /* Sniffit Plugins file */ #ifdef INCLUDE_INTERFACE #include "sn_interface.h" /* all ncurses stuff */ #endif #ifdef GENERATION #include "sn_generation.h" /* Sniffit Packet generation */ #endif #include "sniffit.h" /* definition of functions */ static char Copyright[] = "Sniffit - Brecht Claerhout - Copyright 1996-98"; void quit (char *prog_name) /* Learn to use the program */ { printf ( "usage: %s [-xdabvnN] [-P proto] [-A char] [-p port] [(-r|-R) recordfile]\n" " [-l sniflen] [-L logparam] [-F snifdevice] [-M plugin]\n", prog_name); #ifdef INCLUDE_INTERFACE printf ( " [-D tty]" " (-t | -s)" " | (-i|-I) | -c]\n"); #else printf ( " (-t | -s) | -c]\n"); #endif printf ("Plugins Available:\n"); #ifdef PLUGIN0_NAME printf (" 0 -- %s\n", PLUGIN0_NAME); #endif #ifdef PLUGIN1_NAME printf (" 1 -- %s\n", PLUGIN1_NAME); #endif #ifdef PLUGIN2_NAME printf (" 2 -- %s\n", PLUGIN2_NAME); #endif #ifdef PLUGIN3_NAME printf (" 3 -- %s\n", PLUGIN3_NAME); #endif #ifdef PLUGIN4_NAME printf (" 4 -- %s\n", PLUGIN4_NAME); #endif #ifdef PLUGIN5_NAME printf (" 5 -- %s\n", PLUGIN5_NAME); #endif #ifdef PLUGIN6_NAME printf (" 6 -- %s\n", PLUGIN6_NAME); #endif #ifdef PLUGIN7_NAME printf (" 7 -- %s\n", PLUGIN7_NAME); #endif #ifdef PLUGIN8_NAME printf (" 8 -- %s\n", PLUGIN8_NAME); #endif #ifdef PLUGIN9_NAME printf (" 9 -- %s\n", PLUGIN9_NAME); #endif exit (0); } void close_dumpfile(void) {pcap_dump_close(dev_dump);}; void close_pcapdev(void) {pcap_close(dev_desc);}; void my_exit (void) { fflush(NULL); printf("Gracefull shutdown...\n"); exit (0); }; /* DEBUGGING INFO */ #ifdef DEBUG void close_debug_device (void) { fclose (debug_dev); } void debug_msg (char *debug_text) { fprintf (debug_dev, "%s (%d)\n", debug_text, debug_cnt); debug_cnt++; } #endif char *strlower (char *string) { int i; for (i = 0; i < strlen (string); i++) *(string + i) = (isupper (*(string + i)) ? tolower (*(string + i)) : *(string + i)); return string; } void start_plugin (int PL_nr, struct Plugin_data *PL_d) { switch (PL_nr) { #ifdef PLUGIN0_NAME case 0: PLUGIN0 (PL_d); break; #endif #ifdef PLUGIN1_NAME case 1: PLUGIN1 (PL_d); break; #endif #ifdef PLUGIN2_NAME case 2: PLUGIN2 (PL_d); break; #endif #ifdef PLUGIN3_NAME case 3: PLUGIN3 (PL_d); break; #endif #ifdef PLUGIN4_NAME case 4: PLUGIN4 (PL_d); break; #endif #ifdef PLUGIN5_NAME case 5: PLUGIN5 (PL_d); break; #endif #ifdef PLUGIN5_NAME case 5: PLUGIN5 (PL_d); break; #endif #ifdef PLUGIN6_NAME case 6: PLUGIN6 (PL_d); break; #endif #ifdef PLUGIN7_NAME case 7: PLUGIN7 (PL_d); break; #endif #ifdef PLUGIN8_NAME case 8: PLUGIN8 (PL_d); break; #endif #ifdef PLUGIN9_NAME case 9: PLUGIN9 (PL_d); break; #endif default: fprintf (stderr, "Plugin does not exist...\n"); exit (1); break; } } void reset_all (void) { start_dynam = NULL; dynam_len = 0; } /* if do_file == 0, then don't handle the files */ /* this is for the global logfile option */ struct file_info * add_dynam (char *file, char ptype, char do_file, _32_bit cur_seq, int len) { int i; FILE *f; int last_time_out = 0; struct file_info *dummy_pointer; struct file_info *search_pointer; if (dynam_len >= MAXCOUNT) { /* * remove less effective connection from list */ search_pointer = start_dynam; dummy_pointer = start_dynam; do { if (search_pointer->time_out > last_time_out) { last_time_out = search_pointer->time_out; dummy_pointer = search_pointer; } search_pointer = search_pointer->next; } while (search_pointer != NULL); #ifdef DEBUG debug_msg ("Auto timeout engaged (filename follows)"); debug_msg (dummy_pointer->filename); #endif if (dummy_pointer->f == NULL) delete_dynam (dummy_pointer->filename, dummy_pointer->proto, 0); else delete_dynam (dummy_pointer->filename, dummy_pointer->proto, 1); printf ("Too many connections... auto timeout\n"); } if ((dummy_pointer = (struct file_info *) malloc (sizeof (struct file_info))) == NULL) { printf ("Couldn't allocate memory.\n"); exit (0); }; dummy_pointer->bytes = 0; dummy_pointer->proto = ptype; strcpy (dummy_pointer->filename, file); if (do_file != 0) { f = fopen (file, "a"); if (f == NULL) perror ("Couldn't open logfile:"), exit (0); dummy_pointer->f = f; } else { dummy_pointer->f = NULL; } dummy_pointer->next = NULL; dummy_pointer->buffer = NULL; dummy_pointer->log = 0; dummy_pointer->exp_seq = cur_seq + len; for (i = 0; i < SCBUF; i++) dummy_pointer->scroll_buf[i] = ' '; dummy_pointer->scroll_buf[SCBUF] = 0; if (start_dynam == NULL) start_dynam = dummy_pointer; else { search_pointer = start_dynam; while (search_pointer->next != NULL) search_pointer = search_pointer->next; search_pointer->next = dummy_pointer; } dynam_len++; return dummy_pointer; } void delete_dynam (char *file, char ptype, char do_file) { struct file_info *search_pointer; struct file_info *dummy_pointer; if (start_dynam == NULL) return; search_pointer = start_dynam; if ((strcmp (search_pointer->filename, file) == 0) && (search_pointer->proto == ptype)) { if (do_file != 0) fclose (search_pointer->f); start_dynam = search_pointer->next; dynam_len--; return; } search_pointer = start_dynam; if (search_pointer->next == NULL) return; while (search_pointer->next != NULL) { if ((strcmp (search_pointer->next->filename, file) == 0) && (search_pointer->next->proto == ptype)) { if (do_file != 0) fclose (search_pointer->next->f); dummy_pointer = search_pointer->next; search_pointer->next = search_pointer->next->next; if (dummy_pointer->buffer != NULL) free (dummy_pointer->buffer); free (dummy_pointer); dynam_len--; return; } search_pointer = search_pointer->next; } } /* returns NULL on failure */ struct file_info * search_dynam (char *file, char ptype) { struct file_info *search_pointer; if (start_dynam == NULL) return NULL; search_pointer = start_dynam; /* time_out add */ do { search_pointer->time_out += 1; search_pointer = search_pointer->next; } while (search_pointer != NULL); search_pointer = start_dynam; /* actual search */ do { if ((strcmp (search_pointer->filename, file) == 0) && (search_pointer->proto == ptype)) { search_pointer->time_out = 0; /* timeout reset */ return search_pointer; } search_pointer = search_pointer->next; } while (search_pointer != NULL); return NULL; } /* Type 0: TELNET */ void record_buf (struct file_info *dummy_pointer, _32_bit cur_seq_nr, char *data, int len, int type) { int i, j, noloop = 0; if (dummy_pointer->exp_seq != cur_seq_nr) { return; } noloop = 0; for (i = 0; i < len; i++) { j = dummy_pointer->bytes; switch (type) { case 0: if (data[i] == TELNET_ENTER) /* return found */ { dummy_pointer->log++; noloop = 1; }; break; default: break; } if (noloop == 1) break; if (j >= LOG_PASS_BUF) break; if (isprint (data[i])) { dummy_pointer->buffer[j] = data[i]; } else { dummy_pointer->buffer[j] = '~'; }; dummy_pointer->buffer[j + 1] = 0; dummy_pointer->bytes += 1; } #ifdef DEBUG_ONSCREEN printf ("Record buffer: >%s< (%d)\n", dummy_pointer->buffer, dummy_pointer->bytes); #endif } void sb_shift (struct file_info *dummy_pointer) { int i, j; for (i = 1; i < SCBUF; i++) dummy_pointer->scroll_buf[i - 1] = dummy_pointer->scroll_buf[i]; } void sbuf_update (struct file_info *dummy_pointer, _32_bit cur_seq_nr, char *data, int len) { int i; if (dummy_pointer->exp_seq != cur_seq_nr) { return; } for (i = 0; i < len; i++) { sb_shift (dummy_pointer); if (data[i] != 0) /* * used to be 'isprint', not possible for ftp logging */ { dummy_pointer->scroll_buf[SCBUF - 1] = data[i]; } else { dummy_pointer->scroll_buf[SCBUF - 1] = '.'; }; } #ifdef DEBUG_ONSCREEN printf ("scr_buf: %s\n", dummy_pointer->scroll_buf); #endif } void print_iphead (struct IP_header *iphead, char icmp_or_plain) { int dummy; unsigned char *so, *dest; if (icmp_or_plain != 0) printf ("ICMP message concerned following IP packet:\n"); so = (unsigned char *) &(iphead->source); dest = (unsigned char *) &(iphead->destination); printf ("from %u.%u.%u.%u to %u.%u.%u.%u\n", so[0], so[1], so[2], so[3], dest[0], dest[1], dest[2], dest[3]); dummy = iphead->type; dummy >>= 5; printf ("IP Packet precedence: %s (%c%c%c)\n", IP_TYPE_precedence[dummy], (iphead->type & IP_DELAY) ? 'D' : '-', (iphead->type & IP_THROUGHPUT) ? 'T' : '-', (iphead->type & IP_RELIABILITY) ? 'R' : '-'); dummy = ntohs (iphead->flag_offset); dummy >>= 13; printf ("ID: 0x%X FLAGS: %s %s Time to live (secs): %d\n", ntohs(iphead->ID), (dummy & IP_DF) ? "DF" : "--", (dummy & IP_MF) ? "MF" : "--", iphead->TTL); if (iphead->protocol < 34) printf ("Protocol (%d): %s\n", iphead->protocol, IP_PROTOCOL_number[iphead->protocol]); else printf ("Protocol (%d) not recognised\n", iphead->protocol); printf ("\n"); } 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) /* MODE 0: -t MODE 1: -s */ /* MODE 2: -b */ { unsigned char *so, *dest; char wc_so[20], wc_dest[20]; struct IP_header iphead; struct TCP_header tcphead; struct ICMP_header icmphead; struct UDP_header udphead; int proto; unsigned int prior; char selected; int i; /* Wildcard stuff */ unsigned char *str_IP; unsigned int n_s; /* strlen short notation for wc bugfix */ proto = unwrap_packet (sp, info); if(proto == NOT_SUPPORTED) { #ifdef DEBUG_ONSCREEN printf("unwrap: NOT_SUPPORTED\n"); #endif return DROP_PACKET;} /* no use in trying */ if(proto == NO_IP) { #ifdef DEBUG_ONSCREEN printf("unwrap: NO_IP\n"); #endif return DROP_PACKET;} /* no use in trying */ if(proto == NO_IP_4) { #ifdef DEBUG_ONSCREEN printf("unwrap: NO_IP_4\n"); #endif return DROP_PACKET;} /* no use in trying */ if(proto == CORRUPT_IP) { #ifdef DEBUG_ONSCREEN printf("unwrap: CORRUPT_IP\n"); #endif printf("Suspicious Packet detected... \n"); return DROP_PACKET;} memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header)); so = (unsigned char *) &(iphead.source); dest = (unsigned char *) &(iphead.destination); if ( ((proto == TCP)||(proto==TCP_FRAG_HEAD)) && (PROTOCOLS & F_TCP)) { #ifdef DEBUG_ONSCREEN printf ("TCP Packet\n"); #endif if((info->FRAG_nf==0)&&(proto!=TCP_FRAG_HEAD)) { memcpy (&tcphead, (sp + PROTO_HEAD + info->IP_len), sizeof (struct TCP_header)); memcpy (detail, &tcphead, sizeof (struct TCP_header)); } if ((WILDCARD == 0) && (CFG_FILE == 0)) /* Selection criteria */ { if (MODE == DEST && ipaddr != iphead.destination /* -t */ || MODE == SOURCE && ipaddr != iphead.source /* -s */ || MODE == BOTH && ipaddr != iphead.destination /* -b */ && ipaddr != iphead.source ) return DONT_EXAMINE; /* Check destination/source IP */ } else { if (WILDCARD != 0) /* Wildcards */ { #ifdef DEBUG_ONSCREEN printf ("WILDCARD\n"); #endif sprintf (wc_so, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]); sprintf (wc_dest, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]); n_s = strlen (IP); if (MODE == DEST && (strncmp (wc_dest, IP, n_s) != 0) /* -t */ || MODE == SOURCE && (strncmp (wc_so, IP, n_s) != 0) /* -s */ || MODE == BOTH && (strncmp (wc_dest, IP, n_s) != 0) /* -b */ && (strncmp (wc_so, IP, n_s) != 0) ) return DONT_EXAMINE; /* Check destination/source IP */ } else { /* We are using the config file (4*Check) */ prior = 0; selected = 0; sprintf (wc_so, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]); sprintf (wc_dest, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]); #ifdef DEBUG_ONSCREEN if((info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD)) printf ("CONCERNING: %s %d - %s %d\n", wc_so, ntohs (tcphead.source), wc_dest, ntohs (tcphead.destination)); #endif /* Highest prior last (backward+break for speed) */ for (i = (select_from_length - 1); i >= 0; i--) { if (prior > select_from_list[i].priority) break; str_IP = select_from_list[i].host; #ifdef DEBUG_ONSCREEN printf ("SF: %s %d Prior:%d\n", str_IP, select_from_list[i].port, select_from_list[i].priority); #endif /* tcphead is reserved anyway (even when fragmented) */ if ((select_from_list[i].port == 0) || (select_from_list[i].port == ntohs (tcphead.source)) || (info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD) ) { if (select_from_list[i].wildcard == 0) { /* NO wildcard */ if (strcmp (wc_so, str_IP) == 0) { selected = 1; prior = select_from_list[i].priority; break; } } else { /* wildcard */ if (strncmp (wc_so, str_IP, strlen (str_IP)) == 0) { selected = 1; prior = select_from_list[i].priority; break; } } if (str_IP[0] == 0) { selected = 1; break; }; } } for (i = (select_to_length - 1); i >= 0; i--) { if (prior > select_to_list[i].priority) break; str_IP = select_to_list[i].host; #ifdef DEBUG_ONSCREEN printf ("ST: %s %d Prior:%d\n", str_IP, select_to_list[i].port, select_to_list[i].priority); #endif if ((select_to_list[i].port == 0) || (select_to_list[i].port == ntohs (tcphead.destination))|| (info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD) ) { if (select_to_list[i].wildcard == 0) { /* NO wildcard */ if (strcmp (wc_dest, str_IP) == 0) { selected = 1; prior = select_to_list[i].priority; break; } } else { /* wildcard */ if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0) { selected = 1; prior = select_to_list[i].priority; break; } } if (str_IP[0] == 0) { selected = 1; break; }; } } for (i = (deselect_from_length - 1); i >= 0; i--) { if (prior > deselect_from_list[i].priority) break; str_IP = deselect_from_list[i].host; #ifdef DEBUG_ONSCREEN printf ("DF: %s %d Prior:%d\n", str_IP, deselect_from_list[i].port, deselect_from_list[i].priority); #endif if ((deselect_from_list[i].port == 0) || (deselect_from_list[i].port == ntohs (tcphead.source))|| (info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD) ) { if (deselect_from_list[i].wildcard == 0) { /* NO wildcard */ if (strcmp (wc_so, str_IP) == 0) { selected = 0; prior = deselect_from_list[i].priority; break; } } else { /* wildcard */ if (strcmp (wc_so, str_IP) == 0) { selected = 0; prior = deselect_from_list[i].priority; break; } } if (str_IP[0] == 0) { selected = 0; break; }; } } for (i = (deselect_to_length - 1); i >= 0; i--) { if (prior > deselect_to_list[i].priority) break; str_IP = deselect_to_list[i].host; #ifdef DEBUG_ONSCREEN printf ("DT: %s %d Prior:%d\n", str_IP, deselect_to_list[i].port, deselect_to_list[i].priority); #endif if ((deselect_to_list[i].port == 0) || (deselect_to_list[i].port == ntohs (tcphead.destination))|| (info->FRAG_nf!=0)||(proto==TCP_FRAG_HEAD) ) { if (deselect_to_list[i].wildcard == 0) { /* NO wildcard */ if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0) { selected = 0; prior = deselect_to_list[i].priority; break; } } else { /* wildcard */ if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0) { selected = 0; prior = deselect_to_list[i].priority; break; } } if (str_IP[0] == 0) { selected = 0; break; }; } } #ifdef DEBUG_ONSCREEN printf ("Selected: %d\n", selected); #endif if (selected == 0) return DONT_EXAMINE; } } if( (info->FRAG_nf==0)&&(proto!=TCP_FRAG_HEAD) ) if( (MODE!=BOTH && DEST_PORT && ntohs (tcphead.destination)!=DEST_PORT) || (MODE!=BOTH && SRC_PORT && ntohs (tcphead.source)!=SRC_PORT) || (MODE==BOTH && SRC_PORT && ntohs (tcphead.source)!=SRC_PORT && ntohs (tcphead.destination)!=SRC_PORT) ) /* with BOTH SRC_PORT&DEST_PORT should be the same!! */ /* DEST/SRC do not depend on the SOURCE or DEST modes! */ return DONT_EXAMINE; /* Check dest. PORT */ #ifdef DEBUG_ONSCREEN printf ("Packet accepted\n"); #endif if( (info->FRAG_nf==0)&&(proto!=TCP_FRAG_HEAD) ) { /* inet_ntoa gave wrong output sometimes */ sprintf (file, "%u.%u.%u.%u.%u-%u.%u.%u.%u.%u", so[0], so[1], so[2], so[3], (unsigned short) ntohs (tcphead.source), dest[0], dest[1], dest[2], dest[3], (unsigned short) ntohs (tcphead.destination)); sprintf (file2, "%u.%u.%u.%u.%u-%u.%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3], (unsigned short) ntohs (tcphead.destination), so[0], so[1], so[2], so[3], (unsigned short) ntohs (tcphead.source)); } else { /* inet_ntoa gave wrong output sometimes */ sprintf (file, "%u.%u.%u.%u-%u.%u.%u.%u", so[0], so[1], so[2], so[3], dest[0], dest[1], dest[2], dest[3]); sprintf (file2, "%u.%u.%u.%u-%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3], so[0], so[1], so[2], so[3]); } if(info->FRAG_nf!=0) return TCP_EX_FRAG_NF; if(proto==TCP_FRAG_HEAD) return TCP_EX_FRAG_HEAD; if ((ntohs(tcphead.offset_flag) & FIN) != 0) /* check for reset conn. */ return TCP_FINISH; /* packet is a FIN */ if ((ntohs(tcphead.offset_flag) & RST) != 0) /* check for reset conn. */ return TCP_FINISH; /* * Used to be for speed, '-x' needs all info, so this too! * if (info->DATA_len == 0) * return DONT_EXAMINE; */ return TCP_EXAMINE; /* interprete packet */ }; /***** WARNING: Remove if later fragment handling is done *************/ if(info->FRAG_nf!=0) {printf("Fragment Skipped...\n"); return DONT_EXAMINE; }; if ((proto == ICMP) && (PROTOCOLS & F_ICMP)) /* ICMP packet checking */ { memcpy (&icmphead, (sp + PROTO_HEAD + info->IP_len), sizeof (struct ICMP_header)); memcpy (detail, &icmphead, sizeof (struct ICMP_header)); sprintf (file, "%u.%u.%u.%u > %u.%u.%u.%u", so[0], so[1], so[2], so[3], dest[0], dest[1], dest[2], dest[3]); return ICMP_EXAMINE; }; if ((proto == UDP) && (PROTOCOLS & F_UDP)) /* UDP packet checking */ { #ifdef DEBUG_ONSCREEN printf ("UDP Packet\n"); #endif memcpy (&udphead, (sp + PROTO_HEAD + info->IP_len), sizeof (struct UDP_header)); memcpy (detail, &udphead, sizeof (struct UDP_header)); if ((WILDCARD == 0) && (CFG_FILE == 0)) /* Selection criteria */ { if (MODE == DEST && ipaddr != iphead.destination /* -t */ || MODE == SOURCE && ipaddr != iphead.source /* -s */ || MODE == BOTH && ipaddr != iphead.destination /* -b */ && ipaddr != iphead.source ) return DONT_EXAMINE; /* Check destination/source IP */ } else { if (WILDCARD != 0) /* Wildcards */ { sprintf (wc_so, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]); sprintf (wc_dest, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]); n_s = strlen (IP); if (MODE == DEST && (strncmp (wc_dest, IP, n_s) != 0) /* -t */ || MODE == SOURCE && (strncmp (wc_so, IP, n_s) != 0) /* -s */ || MODE == BOTH && (strncmp (wc_dest, IP, n_s) != 0) /* -b */ && (strncmp (wc_so, IP, n_s) != 0) ) return DONT_EXAMINE; /* Check destination/source IP */ } else { /* We are using the config file (4*Check) */ prior = 0; selected = 0; sprintf (wc_so, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]); sprintf (wc_dest, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]); #ifdef DEBUG_ONSCREEN printf ("CONCERNING: %s %d - %s %d\n", wc_so, ntohs (udphead.source), wc_dest, ntohs (udphead.destination)); #endif /* Highest prior last (backward+break for speed) */ for (i = (select_from_length - 1); i >= 0; i--) { if (prior > select_from_list[i].priority) break; str_IP = select_from_list[i].host; #ifdef DEBUG_ONSCREEN printf ("SF: %s %d Prior:%d\n", str_IP, select_from_list[i].port, select_from_list[i].priority); #endif if ((select_from_list[i].port == 0) || (select_from_list[i].port == ntohs (udphead.source))) { if (select_from_list[i].wildcard == 0) { /* * NO wildcard */ if (strcmp (wc_so, str_IP) == 0) { selected = 1; prior = select_from_list[i].priority; break; } } else { /* * wildcard */ if (strncmp (wc_so, str_IP, strlen (str_IP)) == 0) { selected = 1; prior = select_from_list[i].priority; break; } } if (str_IP[0] == 0) { selected = 1; break; }; } } for (i = (select_to_length - 1); i >= 0; i--) { if (prior > select_to_list[i].priority) break; str_IP = select_to_list[i].host; #ifdef DEBUG_ONSCREEN printf ("ST: %s %d Prior:%d\n", str_IP, select_to_list[i].port, select_to_list[i].priority); #endif if ((select_to_list[i].port == 0) || (select_to_list[i].port == ntohs (udphead.destination))) { if (select_to_list[i].wildcard == 0) { /* * NO wildcard */ if (strcmp (wc_dest, str_IP) == 0) { selected = 1; prior = select_to_list[i].priority; break; } } else { /* * wildcard */ if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0) { selected = 1; prior = select_to_list[i].priority; break; } } if (str_IP[0] == 0) { selected = 1; break; }; } } for (i = (deselect_from_length - 1); i >= 0; i--) { if (prior > deselect_from_list[i].priority) break; str_IP = deselect_from_list[i].host; #ifdef DEBUG_ONSCREEN printf ("DF: %s %d Prior:%d\n", str_IP, deselect_from_list[i].port, deselect_from_list[i].priority); #endif if ((deselect_from_list[i].port == 0) || (deselect_from_list[i].port == ntohs (udphead.source))) { if (deselect_from_list[i].wildcard == 0) { /* NO wildcard */ if (strcmp (wc_so, str_IP) == 0) { selected = 0; prior = deselect_from_list[i].priority; break; } } else { /* wildcard */ if (strcmp (wc_so, str_IP) == 0) { selected = 0; prior = deselect_from_list[i].priority; break; } } if (str_IP[0] == 0) { selected = 0; break; }; } } for (i = (deselect_to_length - 1); i >= 0; i--) { if (prior > deselect_to_list[i].priority) break; str_IP = deselect_to_list[i].host; #ifdef DEBUG_ONSCREEN printf ("DT: %s %d Prior:%d\n", str_IP, deselect_to_list[i].port, deselect_to_list[i].priority); #endif if ((deselect_to_list[i].port == 0) || (deselect_to_list[i].port == ntohs (udphead.destination))) { if (deselect_to_list[i].wildcard == 0) { /* NO wildcard */ if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0) { selected = 0; prior = deselect_to_list[i].priority; break; } } else { /* wildcard */ if (strncmp (wc_dest, str_IP, strlen (str_IP)) == 0) { selected = 0; prior = deselect_to_list[i].priority; break; } } if (str_IP[0] == 0) { selected = 0; break; }; } } #ifdef DEBUG_ONSCREEN printf ("Selected: %d\n", selected); #endif if (selected == 0) return DONT_EXAMINE; } } if( (MODE!=BOTH && DEST_PORT && ntohs (udphead.destination)!=DEST_PORT) || (MODE!=BOTH && SRC_PORT && ntohs (udphead.source)!=SRC_PORT) || (MODE==BOTH && SRC_PORT && ntohs (udphead.source)!=SRC_PORT && ntohs (udphead.destination)!=SRC_PORT) ) /* with BOTH SRC_PORT&DEST_PORT should be the same!! */ /* DEST/SRC do not depend on the SOURCE or DEST modes! */ return DONT_EXAMINE; /* Check dest. PORT */ /* inet_ntoa gave wrong output sometimes */ sprintf (file, "%u.%u.%u.%u.%u-%u.%u.%u.%u.%u", so[0], so[1], so[2], so[3], (unsigned short) ntohs (udphead.source), dest[0], dest[1], dest[2], dest[3], (unsigned short) ntohs (udphead.destination)); sprintf (file2, "%u.%u.%u.%u.%u-%u.%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3], (unsigned short) ntohs (udphead.destination), so[0], so[1], so[2], so[3], (unsigned short) ntohs (udphead.source)); return UDP_EXAMINE; /* interprete packet */ } return DONT_EXAMINE; } /* Default Processing of packets */ pcap_handler packethandler (unsigned char *ipaddrpoint, const struct packetheader * p_header, const unsigned char *sp) { char filename[50], filename2[50], header[SNAPLEN]; FILE *f; struct file_info *dummy_pointer; unsigned char status = 0; char *help; int dummy, finish; /* look out it's signed */ unsigned long datalen, position, total_length, i, n; _32_bit ipaddr; struct unwrap info; struct IP_header iphead; struct TCP_header tcphead; struct ICMP_header icmphead; struct IP_header iphead_icmp; struct UDP_header udphead; struct Plugin_data PL_d, PL_dex; memcpy (&ipaddr, ipaddrpoint, sizeof (_32_bit)); finish = check_packet (ipaddr, p_header, sp, filename, filename2, &info, header, SNIFMODE); if (finish == DROP_PACKET) return; /* Packet is broken */ if( (PROTOCOLS&F_IP)&&((PROTOCOLS&F_TCP)==0)) memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header)), print_iphead (&iphead, 0); if (finish == DONT_EXAMINE) return; /* Packet is not for us */ if(DUMPMODE==8) /* Recording */ { pcap_dump((unsigned char *) dev_dump, p_header, sp); return; } if((PROTOCOLS & F_IP)&&(PROTOCOLS & F_TCP)&&(finish<10)) memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header)), print_iphead (&iphead, 0); #ifdef DEBUG_ONSCREEN printf ("Processing Packet (finish: %d)\n", finish); #endif if ((finish < 10) || (finish >= 20 && finish < 30)) /* Start plugin */ { if( (finish!=TCP_EX_FRAG_HEAD)&&(finish!=TCP_EX_FRAG_NF) ) { /* no fragments to PLUGINS yet */ /* fixing data structure */ memcpy (&(PL_d.PL_info), &info, sizeof (struct unwrap)); memcpy (&(PL_d.PL_iphead), (sp + PROTO_HEAD), sizeof (struct IP_header)); memcpy (&(PL_d.PL_tcphead), (sp + PROTO_HEAD + info.IP_len), sizeof (struct TCP_header)); memcpy (&(PL_d.PL_udphead), (sp + PROTO_HEAD + info.IP_len), sizeof (struct UDP_header)); if (PL_d.PL_iphead.protocol == TCP) memcpy (PL_d.PL_data, (sp + PROTO_HEAD + info.IP_len + info.TCP_len), info.DATA_len); if (PL_d.PL_iphead.protocol == UDP) memcpy (PL_d.PL_data, (sp + PROTO_HEAD + info.IP_len + info.UDP_len), info.DATA_len); memcpy (PL_d.PL_packet, (sp + PROTO_HEAD), info.IP_len + info.TCP_len + info.UDP_len + info.DATA_len); /* starting all plugins */ for (i = 0; i < 10; i++) if (Plugin_Active[i] == 1) { memcpy (&PL_dex, &PL_d, sizeof (struct Plugin_data)); start_plugin (i, &PL_dex); } } } if ((DUMPMODE & 32) && (finish < 10)) /* extended info TCP only */ { if( (finish!=TCP_EX_FRAG_HEAD)&&(finish!=TCP_EX_FRAG_NF) ) { memcpy (&tcphead, header, sizeof (struct TCP_header)); dummy = ntohs (tcphead.offset_flag); printf ("\n"); printf ("TCP Packet ID (from_IP.port-to_IP.port): %s\n", filename); printf (" SEQ (hex): %lX ", ntohl (tcphead.seq_nr)); if (dummy & ACK) printf ("ACK (hex): %lX\n", ntohl (tcphead.ACK_nr)); printf (" FLAGS: %c%c%c%c%c%c", (dummy & URG) ? 'U' : '-', (dummy & ACK) ? 'A' : '-', (dummy & PSH) ? 'P' : '-', (dummy & RST) ? 'R' : '-', (dummy & SYN) ? 'S' : '-', (dummy & FIN) ? 'F' : '-'); if (dummy & ACK) printf (" Window: %X\n", ntohs (tcphead.window)); else printf ("\n"); } }; if ((finish < 10) && (LOGPARAM == 0)) /* TCP packet */ /* I didn't use flags for later extention, and they */ /* don't come in pairs anyhow */ /* use return instead of else {if}, for later extention */ { if( (finish!=TCP_EX_FRAG_HEAD)&&(finish!=TCP_EX_FRAG_NF) ) memcpy (&tcphead, header, sizeof (struct TCP_header)); switch (DUMPMODE & 199) /* without bit 3,4,5 (8,16,32) */ { case 0: /* LOG mode */ if( (finish==TCP_EX_FRAG_HEAD)||(finish==TCP_EX_FRAG_NF) ) break; /* no FRAG handling in log mode yet */ status = 0; dummy_pointer = search_dynam (filename, TCP); if (dummy_pointer != NULL) status = 1; /* make a new entry unless it's reset */ if (status == 0) { if (finish == TCP_FINISH) return; /* there was never data transmitted */ /* seq_nr & datalen not important here yet */ if ((dummy_pointer = add_dynam (filename, TCP, 1, 0, 0)) == NULL) return; } f = dummy_pointer->f; if (dummy_pointer->bytes <= SNIFLEN) { const unsigned char *data= sp + PROTO_HEAD + info.IP_len + info.TCP_len; if (SNIFLEN != 0) dummy_pointer->bytes += info.DATA_len; /* last packet is written */ /* don't care about length */ if (ASC == 0) { for (i = 0; i < info.DATA_len; i++) fprintf (f, "%c", data[i]); } else { for (i = 0; i < info.DATA_len; i++) fprintf (f, "%c", isprint (data[i]) ? data[i] : non_printable); }; fflush (f); /* write all */ } if (finish == TCP_FINISH) /* let's reset the connection */ delete_dynam (filename, TCP, 1); break; case 1: /* DUMP mode */ case 2: case 3: memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header)); printf ("Packet ID (from_IP.port-to_IP.port): %s\n", filename); total_length = info.IP_len + info.TCP_len + info.DATA_len; if(info.FRAG_f!=0) printf("The following packet is an IP Fragment (first/ID: %0X)...\n", ntohs(iphead.ID)); if( (finish==TCP_EX_FRAG_HEAD)||(finish==TCP_EX_FRAG_NF) ) { total_length = info.IP_len + info.DATA_len; if(finish==TCP_EX_FRAG_HEAD) printf("WARNING: Fragmented TCP header... suspicious... (ID: %0X) \n", ntohs(iphead.ID)); if(finish==TCP_EX_FRAG_NF) printf("The following packet is a continued IP Fragment (ID: %0X)...\n", ntohs(iphead.ID)); }; n = 0; for (i = 0; i < total_length; i++) { unsigned char c = sp[PROTO_HEAD + i]; if (n > 75) n = 0, printf ("\n"); if (DUMPMODE & 1) n += printf (" %02X", c); if (DUMPMODE & 2) n += printf (" %c", isprint (c) ? c : '.'); } printf ("\n\n"); break; case 128: break; /* NO LOGGING MODE */ default: printf ("\nYou mixed incompatible options!\n"); exit (1); } return; } if ((finish < 10) && (LOGPARAM != 0)) /* TCP packet - logfile */ /* This mode will grow, so I just copied the other if() */ /* instead of adding a dumpmode, I think this will keep */ /* things more simpel. Also I use the smart dynam */ /* managment of connections */ { if( (finish!=TCP_EX_FRAG_HEAD)&&(finish!=TCP_EX_FRAG_NF) ) { /* no FRAG handling in logfile mode yet */ #include "sn_analyse.c" /* dirty, but it got too confusing */ } } if (finish < 20) /* ICMP packet */ { memcpy (&icmphead, header, sizeof (struct ICMP_header)); memcpy (&iphead_icmp, (sp + PROTO_HEAD + info.IP_len + ICMP_HEADLENGTH + 4), sizeof (struct IP_header)); printf ("ICMP message id: %s\n", filename); printf (" ICMP type: "); switch (icmphead.type) { case 0: printf ("%s\n", ICMP_TYPE_0); break; case 3: printf ("%s\n", ICMP_TYPE_3); printf (" Error: %s\n", ICMP_type_3_code[icmphead.code]); print_iphead (&iphead_icmp, 1); break; case 4: printf ("%s\n", ICMP_TYPE_4); print_iphead (&iphead_icmp, 1); break; case 5: printf ("%s\n", ICMP_TYPE_5); printf (" Error: %s\n", ICMP_type_5_code[icmphead.code]); print_iphead (&iphead_icmp, 1); break; case 8: printf ("%s\n", ICMP_TYPE_8); break; case 11: printf ("%s\n", ICMP_TYPE_11); printf (" Error: %s\n", ICMP_type_11_code[icmphead.code]); print_iphead (&iphead_icmp, 1); break; case 12: printf ("%s\n", ICMP_TYPE_12); print_iphead (&iphead_icmp, 1); break; case 13: printf ("%s\n", ICMP_TYPE_13); break; case 14: printf ("%s\n", ICMP_TYPE_14); break; case 15: printf ("%s\n", ICMP_TYPE_15); break; case 16: printf ("%s\n", ICMP_TYPE_16); break; case 17: printf ("%s\n", ICMP_TYPE_17); break; case 18: printf ("%s\n", ICMP_TYPE_18); break; default: printf ("Unknown ICMP type!\n"); break; } printf ("\n"); return; } if (finish < 30) /* nothing yet */ { memcpy (&udphead, header, sizeof (struct UDP_header)); switch (DUMPMODE & 223) { case 0: break; case 1: /* DUMP mode */ case 2: case 3: printf ("UDP Packet ID (from_IP.port-to_IP.port): %s\n", filename); total_length = info.IP_len + info.UDP_len + info.DATA_len; n = 0; for (i = 0; i < total_length; i++) { unsigned char c = sp[PROTO_HEAD + i]; if (n > 75) n = 0, printf ("\n"); if (DUMPMODE & 1) n += printf (" %02X", c); if (DUMPMODE & 2) n += printf (" %c", isprint (c) ? c : '.'); } printf ("\n\n"); break; case 128: break; /* NO LOGGING MODE */ default: printf ("\nImpossible error! Sniffer Hartattack!\n"); exit (0); } return; } } #ifdef INCLUDE_INTERFACE /* Interactive packethandling */ int check_mask (const struct packetheader *p_header, const unsigned char *sp, char *conn_name, char *conn_name2, char *desc_string, struct unwrap *info) /* return -1 : packet not for us */ /* else finish value */ { char helpstr1[20], helpstr2[20]; unsigned char *so, *dest; struct IP_header iphead; struct TCP_header tcphead; int proto, i,j; proto = unwrap_packet (sp, info); /* Interface, no output allowed to stdout */ if(proto == NOT_SUPPORTED) return DROP_PACKET; /* no use in trying */ if (proto == NO_IP) return DROP_PACKET; /* no use in trying */ if (proto == NO_IP_4) return DROP_PACKET; /* no use in trying */ if(proto == CORRUPT_IP) return DROP_PACKET; /* no use in trying */ if((info->FRAG_nf!=0)||(info->FRAG_f!=0)) {return DONT_EXAMINE; }; /* No fragments studied at all */ (*IP_nr_of_packets)++; if (proto == ICMP) { (*ICMP_nr_of_packets)++; return DONT_EXAMINE; } if (proto == UDP) { (*UDP_nr_of_packets)++; (*UDP_bytes_in_packets) += (info->UDP_len + info->DATA_len + info->IP_len); return DONT_EXAMINE; } if (proto != TCP) return DONT_EXAMINE; /* Packet info */ (*TCP_nr_of_packets)++; (*TCP_bytes_in_packets) += (info->TCP_len + info->DATA_len + info->IP_len); /* Not a TCP packet */ memcpy (&iphead, (sp + PROTO_HEAD), sizeof (struct IP_header)); memcpy (&tcphead, (sp + PROTO_HEAD + info->IP_len), sizeof (struct TCP_header)); if (mask->source_ip != 0 && iphead.source != mask->source_ip) return DONT_EXAMINE; if (mask->destination_ip != 0 && iphead.destination != mask->destination_ip) return DONT_EXAMINE; if (mask->destination_port && ntohs (tcphead.destination) != mask->destination_port) return DONT_EXAMINE; if (mask->source_port && ntohs (tcphead.source) != mask->source_port) return DONT_EXAMINE; /* inet_ntoa gave wrong output sometimes */ so = (unsigned char *) &(iphead.source); dest = (unsigned char *) &(iphead.destination); sprintf (helpstr1, "%u.%u.%u.%u", so[0], so[1], so[2], so[3]); sprintf (helpstr2, "%u.%u.%u.%u", dest[0], dest[1], dest[2], dest[3]); sprintf (conn_name, "%16s %5u -> %16s %5u", helpstr1, ntohs (tcphead.source), helpstr2, ntohs (tcphead.destination)); sprintf (conn_name2, "%16s %5u -> %16s %5u", helpstr2, ntohs (tcphead.destination), helpstr1, ntohs (tcphead.source)); if(INTERACTIVE_EXTEND==1) { #include "sn_conn_desc.c" /* Some detection */ } if ((ntohs (tcphead.offset_flag) & FIN) != 0) /* check for reset conn. */ return TCP_FINISH; /* packet is a FIN */ if ((ntohs (tcphead.offset_flag) & RST) != 0) /* check for reset conn. */ return TCP_FINISH; /* packet is a RST */ if (info->DATA_len == 0) return DONT_EXAMINE; /*packet not for us */ return TCP_EXAMINE; /* interprete packet */ } pcap_handler interactive_packethandler (char *dummy, const struct packetheader * p_header, const unsigned char *sp) { char conn_name[CONN_NAMELEN], conn_name2[CONN_NAMELEN]; char desc_string[DESC_BYTES]; int finish; /* look out it's signed */ struct unwrap info; if(INTERACTIVE_EXTEND==1) strcpy (desc_string, "Unknown"); finish = check_mask (p_header, sp, conn_name, conn_name2, desc_string, &info); if (finish == DROP_PACKET) return; /* Packet is broken */ if (finish == DONT_EXAMINE) return; /* Packet is not for us */ if (finish != TCP_FINISH) /* finish: already logged, or to short to add */ add_itemlist (running_connections, conn_name, desc_string); if (strcmp (log_conn->log_enter, conn_name) == 0) { const unsigned char *data = sp + PROTO_HEAD + info.IP_len + info.TCP_len; if (*DATAlength + info.DATA_len < LENGTH_OF_INTERPROC_DATA) { memcpy ((connection_data + *DATAlength), data, info.DATA_len); *DATAlength += info.DATA_len; } } if (finish == TCP_FINISH) { del_itemlist (running_connections, conn_name); del_itemlist (running_connections, conn_name2); } kill (getppid (), SIGUSR1); } #endif int main (int argc, char *argv[]) { char *dev, forced_dev[20], buffer[SNAPLEN]; char ebuf[PCAP_ERRBUF_SIZE]; unsigned char *DUMPfile; /* file used for packed logging */ int c, i; unsigned long memsize; _32_bit ipaddr; int flag = 0, doboth = 0, FORCE_DEV = 0, SUPPORTED = 0; extern char *optarg; signal (SIGINT, my_exit); /* gracefull termination in different ways */ signal (SIGHUP, my_exit); signal (SIGTERM, my_exit); SNIFLEN = 300; /* Set defaults */ DEST_PORT = SRC_PORT = 0; /* dest & source Port */ INTERACTIVE_EXTEND=SNIFMODE = DUMPMODE = PROTOCOLS = ASC = WILDCARD = CFG_FILE = NO_CHKSUM = 0; LOGPARAM = 0; Logfile[0] = 0; logging_device = NULL; IP[0]=0; for (i = 0; i < 10; i++) Plugin_Active[i] = 0; /* Active plugins */ #ifdef DEBUG if ((debug_dev = fopen (DEBUG_DEVICE, "a")) < 0) { printf ("Couldn't open DEBUG device!\n"); exit (0); } else { fprintf (debug_dev, "\n\nDEVICE OPENED FOR SNIFFIT DEBUGGING\n\n"); exit_func (close_debug_device); } #endif #ifdef INCLUDE_INTERFACE while ((c = getopt (argc, argv, "D:A:P:iIdp:l:xabt:s:F:c:nvL:M:Nr:R:")) != -1) { #else while ((c = getopt (argc, argv, "A:P:dp:l:xabt:s:F:c:nvL:M:Nr:R:")) != -1) { #endif /* Argument treating */ switch (c) { case 'v': printf ("Sniffit Version %s - Copyright 1996-98 Brecht Claerhout\n", VERSION); #ifdef __DATE__ printf ("Binary build %s %s\n", __DATE__, __TIME__); #endif quit (argv[0]); break; case 'd': if(DUMPMODE&8) quit(argv[0]); DUMPMODE |= 1; break; case 'a': if(DUMPMODE&8) quit(argv[0]); DUMPMODE |= 2; break; case 'R': /* recording (not mixable) */ if(DUMPMODE) quit(argv[0]); DUMPMODE=8; DUMPfile=(unsigned char *)optarg; break; case 'r': if(DUMPMODE&8) quit(argv[0]); DUMPMODE|=16; /* reading (mixable) */ DUMPfile=(unsigned char *)optarg; break; case 'x': if(DUMPMODE&8) quit(argv[0]); DUMPMODE |= 32; break; case 'N': if(DUMPMODE&8) quit(argv[0]); DUMPMODE |= 128; break; case 'p': if(DEST_PORT!=0) printf("Conflicting ports... (using %d as destination port)\n", atoi(optarg)); DEST_PORT = atoi(optarg); break; case 'l': SNIFLEN = atol (optarg); break; case 'L': LOGPARAM |= LOGPARAM_LOG_ON; strlower (optarg); if (strstr (optarg, "raw")) LOGPARAM |= LOGPARAM_RAW; if (strstr (optarg, "norm")) LOGPARAM |= LOGPARAM_NORM; if (strstr (optarg, "telnet")) LOGPARAM |= LOGPARAM_TELNET; if (strstr (optarg, "ftp")) LOGPARAM |= LOGPARAM_FTP; if (strstr (optarg, "mail")) LOGPARAM |= LOGPARAM_MAIL; break; case 'b': doboth = 1; break; case 'A': ASC = 1; non_printable = *optarg; break; case 'D': logging_device = optarg; break; case 'P': strlower (optarg); if (strstr (optarg, "tcp")) PROTOCOLS |= F_TCP; if (strstr (optarg, "icmp")) PROTOCOLS |= F_ICMP; if (strstr (optarg, "udp")) PROTOCOLS |= F_UDP; if (strstr (optarg, "ip")) PROTOCOLS |= F_IP; break; case 's': { char hlp[300], *hlp2; flag++; SNIFMODE = SOURCE; hlp[299]=0; strncpy(hlp,optarg,299); hlp2=(char *)strtok(hlp,":"); IP[255]=0; strncpy(IP,hlp2,255); if((hlp2=(char *)strtok(NULL,":"))!=NULL) SRC_PORT = atoi(hlp2); break; } case 't': { char hlp[300], *hlp2; flag++; SNIFMODE = DEST; hlp[299]=0; strncpy(hlp,optarg,299); hlp2=(char *)strtok(hlp,":"); IP[255]=0; strncpy(IP,hlp2,255); if((hlp2=(char *)strtok(NULL,":"))!=NULL) { if(DEST_PORT!=0) printf("Conflicting ports... (using %d as destination port)\n", atoi(hlp2)); DEST_PORT = atoi(hlp2); } break; } case 'i': flag++; SNIFMODE = INTERACTIVE; INTERACTIVE_EXTEND=0; break; case 'I': flag++; SNIFMODE = INTERACTIVE; INTERACTIVE_EXTEND=1; break; case 'n': NO_CHKSUM = 1; break; case 'M': if ((atoi (optarg) >= 0) && (atoi (optarg) <= 9)) Plugin_Active[atoi (optarg)] = 1; break; case 'F': strcpy (forced_dev, optarg); FORCE_DEV = 1; break; case 'c': flag++; read_cfg_file (optarg); #ifdef DEBUG_ONSCREEN printf ("FINISHED INTERPRETING\n"); printf ("sf:%d st:%d df:%d dt:%d\n", select_from_length, select_to_length, deselect_from_length, deselect_to_length); #endif CFG_FILE = 1; break; case '?': quit(argv[0]); break; default: break; } } #ifdef ALLOW_SUID if ((getuid () != 0) && (geteuid () != 0)) printf ("You should be root to run this program!\n"), exit (1); #else if (getuid () != 0) printf ("You should be root to run this program!\n"), exit (1); #endif if (flag != 1) quit (argv[0]); if ((LOGPARAM != 0) && (CFG_FILE == 0)) quit (argv[0]); if (LOGPARAM != 0) open_logfile (); if (PROTOCOLS == 0) PROTOCOLS |= F_TCP; if (doboth) { SNIFMODE = BOTH; if( DEST_PORT&&SRC_PORT&&(DEST_PORT!=SRC_PORT) ) printf("Conflicting ports... (result might not be what you want!)\n"); if(DEST_PORT==0) DEST_PORT=SRC_PORT; /* ports should be the same for BOTH */ else SRC_PORT=DEST_PORT; } if ((SNIFMODE != INTERACTIVE) && (CFG_FILE == 0)) { /* if(index(IP,'@')) For SunOS */ if (strchr (IP, '@')) { printf ("Wildcard detected, IP nr. not checked...\n"); WILDCARD = 1; /* strcpy(index(IP,'@'),"\0"); */ strcpy (strchr (IP, '@'), "\0"); } else { ipaddr = getaddrbyname (IP); if (ipaddr == 0) printf ("Non existing host!\n"), exit (1); } } reset_all (); /* just to be sure */ if(DUMPMODE&16) /* read from a file */ { if(FORCE_DEV==0) quit(argv[0]); if((dev_desc=pcap_open_offline(DUMPfile,ebuf))==NULL) fprintf (stderr,"%s\n",ebuf), exit (0); } /* real device */ if (FORCE_DEV != 0) /* 0.3.6 core dump fix */ { if((dev=malloc(strlen(forced_dev)+1))==NULL) fprintf(stderr,"Couldn't allocate memory...\n"); strcpy (dev, forced_dev); printf ("Forcing device to %s (user requested)...\n", dev); printf ("Make sure you have read the docs carefully.\n"); PROTO_HEAD = FORCED_HEAD_LENGTH; } else { if((dev = pcap_lookupdev (ebuf)) == NULL) fprintf (stderr,"%s\n",ebuf), exit (1); } for (i = 0; i < NETDEV_NR; i++) if (strstr (dev, NETDEV[i])) /* For expansion */ { PROTO_HEAD = HEADSIZE[i]; printf ("Supported Network device found. (%s)\n", dev); SUPPORTED = 1; break; } if ((SUPPORTED == 0) && (FORCE_DEV == 0)) /* not supported & not forced */ { printf ("Network device found... BUT not known by Sniffit, use '-F ' option!\n"); printf ("Read the README.FIRST on how to force network devices.\n"); exit (1); } if(!(DUMPMODE&16)) if ((dev_desc = pcap_open_live (dev, SNAPLEN, 1, MSDELAY, ebuf)) == NULL) fprintf (stderr,"%s\n",ebuf), exit (0); else exit_func(close_pcapdev); if(FORCE_DEV!=0) {free(dev);} /* no longer needed */ #ifdef PLUGIN0_INIT() if (Plugin_Active[0] == 1) PLUGIN0_INIT (); #endif #ifdef PLUGIN1_INIT() if (Plugin_Active[1] == 1) PLUGIN1_INIT (); #endif #ifdef PLUGIN2_INIT() if (Plugin_Active[2] == 1) PLUGIN2_INIT (); #endif #ifdef PLUGIN3_INIT() if (Plugin_Active[3] == 1) PLUGIN3_INIT (); #endif #ifdef PLUGIN4_INIT() if (Plugin_Active[4] == 1) PLUGIN4_INIT (); #endif #ifdef PLUGIN5_INIT() if (Plugin_Active[5] == 1) PLUGIN5_INIT (); #endif #ifdef PLUGIN6_INIT() if (Plugin_Active[6] == 1) PLUGIN6_INIT (); #endif #ifdef PLUGIN7_INIT() if (Plugin_Active[7] == 1) PLUGIN7_INIT (); #endif #ifdef PLUGIN8_INIT() if (Plugin_Active[8] == 1) PLUGIN8_INIT (); #endif #ifdef PLUGIN9_INIT() if (Plugin_Active[9] == 1) PLUGIN9_INIT (); #endif #ifdef INCLUDE_INTERFACE if (SNIFMODE == INTERACTIVE) { memsize = sizeof (int) + sizeof (int) + LENGTH_OF_INTERPROC_DATA + sizeof (int) + sizeof (struct snif_mask) + sizeof (struct shared_logged_conn) + (CONNECTION_CAPACITY * sizeof (struct shared_conn_data)) + sizeof (int) + sizeof (unsigned long) + sizeof (int) + sizeof (int) + sizeof (unsigned long) + sizeof (int) + sizeof (int); memory_id = shmget (0, memsize, 0700); if (memory_id < 0) { perror ("Interactive Sniffer Hartattack (No Shared mem avail!)"); exit (0); } exit_func (mem_exit); if ((SHARED = shmat (memory_id, 0, SHM_RND)) == NULL) { perror ("Interactive Sniffer Hartattack (Wow something is wrong here)"); exit (0); }; printf ("Entering Shared memory at %p\n", SHARED); printf ("Shared %d\n", memsize); timing = SHARED; /* set all pointers */ DATAlength = timing + sizeof (int); connection_data = DATAlength + sizeof (int); LISTlength = connection_data + LENGTH_OF_INTERPROC_DATA; mask = LISTlength + sizeof (int); logged_connections = mask + sizeof (struct snif_mask); log_conn = (struct shared_logged_conn *) logged_connections; running_connections = logged_connections + sizeof (struct shared_logged_conn); TCP_nr_of_packets = running_connections + (sizeof (struct shared_conn_data) * CONNECTION_CAPACITY); TCP_bytes_in_packets = TCP_nr_of_packets + sizeof (int); ICMP_nr_of_packets = TCP_bytes_in_packets + sizeof (unsigned long); UDP_nr_of_packets = ICMP_nr_of_packets + sizeof (int); UDP_bytes_in_packets = UDP_nr_of_packets + sizeof (int); IP_nr_of_packets = UDP_bytes_in_packets + sizeof (unsigned long); DESC_LEN = IP_nr_of_packets + sizeof (int); clear_shared_mem (0); *DESC_LEN = 10; /* not necessary, but for security (eliminate very unlikely races) */ if ((Pid = fork ()) < 0) { perror ("Interactive Sniffer Hartattack (Couldn't fork)"); exit (0); }; if (Pid == 0) { sleep (4); if (pcap_loop (dev_desc, CNT, interactive_packethandler, NULL) < 0) printf ("Capturing Packets Failed\n"), exit (0); } else { exit_func (child_exit); signal (SIGCHLD, SIG_IGN); if (logging_device != NULL) { if (stat (logging_device, &log_dev_stat) < 0) perror ("\'-D\' option error"), exit (0); if ((log_dev_stream = fopen (logging_device, "a")) == NULL) printf ("Couldn't open device for logging output\n"), exit (0); } run_interface (); } } else { #endif if (CFG_FILE == 0) printf ("Sniffit.%s is up and running.... (%s)\n\n", VERSION, IP); else printf ("Sniffit.%s is up and running.... (Config File Used)\n\n", VERSION); if(DUMPMODE&8) { if((dev_dump=pcap_dump_open(dev_desc, DUMPfile))==NULL) fprintf (stderr, "Capturing Packets Failed\n"), exit (0); exit_func(close_dumpfile); } switch (pcap_loop (dev_desc, CNT, packethandler, (unsigned char *) &ipaddr)) { case -1: fprintf (stderr, "Capturing Packets Failed\n"), exit (0); break; case 0: exit(0); default: break; } #ifdef INCLUDE_INTERFACE } #endif }