#include <include.h>
#include <src/interface.h>
#include <src/driver.h>
#include <src/functions.h>
#include <src/analyse.h>
#include <src/scanner.h>
#include <src/crt_io.h>
#include <src/conversion.h>
#include <src/keyboard.h>
#include <src/errmsg.h>
#include <wtap.h>
Go to the source code of this file.
Functions | |
void | Bye (int ExitCode) |
void | HelpAndBye (void) |
void | VersionAndBye (void) |
void | DispConf (ConfigStruct *config) |
void | parse_keystring () |
void | check_keys () |
void | stop_signal (void) |
void | ChangeChannel_th (void *ptr1) |
int | main (int argc, char **argv) |
Variables | |
static UINT8 | ID [] = "$Id: scanner.c 178 2007-08-11 16:57:24Z poggij $" |
ConfigStruct | config |
ScanResult_t | Res |
WINDOW * | Title_WND |
WINDOW * | Panel_WND |
WINDOW * | Sum_WND |
WINDOW * | RealTime_WND |
Statistics_t | Stats |
UINT8 | CursesIsInUse = (UINT8) 0 |
pthread_mutex_t | screen_mutex = PTHREAD_MUTEX_INITIALIZER |
MUTEX for lock screen, so only one func write to it at the same time. | |
pthread_t | thread_ChgChan |
pthread_t | thread_RefreshRTW |
pthread_t | thread_checkkey |
UINT8 | stop_sniffing = (UINT8) 0 |
void Bye | ( | int | ExitCode | ) |
void HelpAndBye | ( | void | ) |
void VersionAndBye | ( | void | ) |
void DispConf | ( | ConfigStruct * | config | ) |
Definition at line 1587 of file functions.c.
References Bye(), ConfigStruct::CheckScreenSize, CISCO_CVS_CARD, ConfigStruct::DateFormat, ConfigStruct::DebugLevel, ConfigStruct::devname, ConfigStruct::devname2, ERROR_UNKNOWN_INTERFACE, FALSE, ConfigStruct::IDS_is_ON, InterfaceIsExistant(), MAX_DEBUG_LEVEL, ConfigStruct::MaxPacket, ConfigStruct::OutDotFileName, ConfigStruct::OutDumpFileName, ConfigStruct::OutFileName, ConfigStruct::SendAlert2Syslog, ConfigStruct::SingleChannel, ConfigStruct::TimeToSleepBeforeChangeChannel, and ConfigStruct::TypeOfCard.
Referenced by main().
01588 { 01589 01590 if (config->TypeOfCard == CISCO_CVS_CARD) { 01591 fprintf(stdout, "Interfaces used: %s and %s \n", config->devname, 01592 config->devname2); 01593 if (InterfaceIsExistant(config->devname2) == FALSE) { 01594 fprintf(stderr, "Arg, the interface %s is not existant\n", 01595 config->devname2); 01596 Bye(ERROR_UNKNOWN_INTERFACE); 01597 } 01598 } else { 01599 fprintf(stdout, "Interface used: %s\n", config->devname); 01600 } 01601 if (InterfaceIsExistant(config->devname) == FALSE) { 01602 fprintf(stderr, "Arg, the interface %s is not existant\n", 01603 config->devname); 01604 Bye(ERROR_UNKNOWN_INTERFACE); 01605 } 01606 01607 fprintf(stdout, "Debug Level: %d", config->DebugLevel); 01608 if (config->DebugLevel == MAX_DEBUG_LEVEL) 01609 fprintf(stdout, " (Crazy level)"); 01610 // Out Files 01611 fprintf(stdout, "\nOutput filename: %s", 01612 (config->OutFileName == NULL) ? "<none>" : config->OutFileName); 01613 fprintf(stdout, "\nPCap dump file: %s", 01614 (config->OutDumpFileName == 01615 NULL) ? "<none>" : config->OutDumpFileName); 01616 fprintf(stdout, "\nDot output filename: %s", 01617 (config->OutDotFileName == 01618 NULL) ? "<none>" : config->OutDotFileName); 01619 01620 fprintf(stdout, "\nChannel scan : %d", config->SingleChannel); 01621 if (config->SingleChannel == 0) 01622 fprintf(stdout, " (All channels)"); 01623 fprintf(stdout, "\nSleep between channel hop: %d", 01624 config->TimeToSleepBeforeChangeChannel); 01625 01626 fprintf(stdout, "\nMax packets before quit: %d", 01627 (int) config->MaxPacket); 01628 if (!config->MaxPacket) 01629 fprintf(stdout, " (Don't quit)"); 01630 fprintf(stdout, "\nDate format: %s", 01631 (config->DateFormat) ? "Timestamp" : "Human readable"); 01632 fprintf(stdout, "\nCurses Screen size detection: %s", 01633 (config->CheckScreenSize) ? "Enabled" : "Disabled"); 01634 fprintf(stdout, "\nIDS active: %s", 01635 (config->IDS_is_ON) ? "Enabled" : "Disabled"); 01636 fprintf(stdout, "\nSend IDS alert to Syslog: %s\n", 01637 (config->SendAlert2Syslog) ? "Enabled" : "Disabled"); 01638 01639 // Add channels per second scan info. 01640 }
void parse_keystring | ( | ) |
Definition at line 49 of file keyboard.c.
References AIRJACK_CARD, CHANNEL_MAX, ConfigStruct::ChannelHop, CLEAR_KEYBOARD_BUFFER, ClearPanel(), debug, ConfigStruct::DebugLevel, ConfigStruct::devname, DISPLAY_ACK_BIT, DISPLAY_BEACON_BIT, DISPLAY_CONTROL_BIT, DISPLAY_DATA_BIT, DISPLAY_PROBE_BIT, DISPLAY_STATION_BIT, ConfigStruct::DoNotDisplay, EXIT_WITH_Q, FALSE, ConfigStruct::FirstNIC, HOP_MAX, HOP_MIN, ConfigStruct::JammingNow, KEYBOARD_BUFFER, keyindex, keystring, MAX_DEBUG_LEVEL, ResetAllDetectedClient(), screen_mutex, selectChannel(), Send_To_All_BSSID_A_Deauth(), ConfigStruct::SingleChannel, stop_sniffing, SWITCH_BIT, TIME_TO_SLEEP_BEFORE_CHANGE_CHANNEL, ConfigStruct::TimeToSleepBeforeChangeChannel, TRUE, ConfigStruct::TypeOfCard, and warning().
Referenced by check_keys_th().
00050 { 00051 register int chan = 0; 00052 register int ret = 0; 00053 00054 switch (keyindex) { 00055 case 1: 00056 switch (keystring[0]) { 00057 case '+': // Go to next channel 00058 case '-': // Go to previous channel 00059 chan = config.SingleChannel; 00060 if ((keystring[0] == '+') 00061 && (config.SingleChannel < 14)) 00062 config.SingleChannel++; 00063 if ((keystring[0] == '-') 00064 && (config.SingleChannel > 0)) 00065 config.SingleChannel--; 00066 00067 config.SingleChannel = (config.SingleChannel % (CHANNEL_MAX + 1)); 00068 00069 ret = selectChannel(config.devname, config.SingleChannel); 00070 if (ret != 0) { 00071 selectChannel(config.devname, chan); // PB, so go back previous channel 00072 config.SingleChannel = chan; 00073 warning("Channel %d is forbidden (%d)\n", chan, ret); 00074 } 00075 CLEAR_KEYBOARD_BUFFER; 00076 break; 00077 case 'a': // Go to next channel 00078 case 'w': // Go to previous channel 00079 if ((keystring[0] == 'a') && (config.FirstNIC > 0)) 00080 config.FirstNIC--; 00081 if (keystring[0] == 'w') 00082 config.FirstNIC++; 00083 debug(3, "config.FirstNIC = %d\n", config.FirstNIC); 00084 CLEAR_KEYBOARD_BUFFER; 00085 break; 00086 case 'q': 00087 warning(" UPPER Q to Quit\n"); 00088 CLEAR_KEYBOARD_BUFFER; 00089 break; 00090 case 'Q': // It's time to exit 00091 // We don't need to stop, if we know that we will stop 00092 if (!stop_sniffing) { 00093 #ifdef WITH_THREAD 00094 // Clean and Force STOP the thread 00095 pthread_mutex_unlock(&screen_mutex); 00096 pthread_mutex_destroy(&screen_mutex); 00097 #endif 00098 warning("Q was hit - sniffing aborted\n\n"); 00099 stop_sniffing = EXIT_WITH_Q; 00100 } 00101 break; 00102 case 'r': 00103 // Do a reset of all captured station 00104 // Thank's to Guillaume Lehembre for the Idea 00105 ResetAllDetectedClient(); 00106 ClearPanel(); 00107 CLEAR_KEYBOARD_BUFFER; 00108 break; 00109 case 's': // change channel more Slowly 00110 if (config.TimeToSleepBeforeChangeChannel < 500) 00111 config.TimeToSleepBeforeChangeChannel += 10; 00112 else 00113 config.TimeToSleepBeforeChangeChannel += 100; 00114 debug(2, 00115 "config.TimeToSleepBeforeChangeChannel = %d ms\n", 00116 config.TimeToSleepBeforeChangeChannel); 00117 CLEAR_KEYBOARD_BUFFER; 00118 break; 00119 case 'f': // change channel more Fast 00120 if (config.TimeToSleepBeforeChangeChannel < 500) 00121 config.TimeToSleepBeforeChangeChannel -= 10; 00122 else 00123 config.TimeToSleepBeforeChangeChannel -= 100; 00124 if (config.TimeToSleepBeforeChangeChannel < 25) 00125 config.TimeToSleepBeforeChangeChannel = 25; 00126 debug(2, 00127 "config.TimeToSleepBeforeChangeChannel = %d ms\n", 00128 config.TimeToSleepBeforeChangeChannel); 00129 CLEAR_KEYBOARD_BUFFER; 00130 break; 00131 case 'd': // default TimeToSleepBeforeChangeChannel 00132 config.TimeToSleepBeforeChangeChannel = 00133 TIME_TO_SLEEP_BEFORE_CHANGE_CHANNEL; 00134 debug(2, 00135 "config.TimeToSleepBeforeChangeChannel = %d ms\n", 00136 config.TimeToSleepBeforeChangeChannel); 00137 CLEAR_KEYBOARD_BUFFER; 00138 break; 00139 case 'h': 00140 warning("Help :\n" "Q for quit\n" 00141 "c??c to scan channel ??\n" 00142 "+ - to increment or decrement channel to scan\n" 00143 "a w to scroll in the upper window\n" 00144 "f s d for scan more fast, more slow and default time\n" 00145 "j+ j- for changing channel hop\n" 00146 "v+ v- for changing verbose level\n" 00147 "n abcdps for hiding/showing Ack, Beacon, Control, Data, Probe and Stations\n" 00148 "r reset all detected packet\n" 00149 "D Send de-authentication to all BSSID\n" 00150 "J Start/Stop jamming\n" 00151 "Q exit, stop, quit, goback home ...\n"); 00152 CLEAR_KEYBOARD_BUFFER; 00153 break; 00154 case 'D': 00155 // Send De-authentification to ALL BSSID :-) 00156 // Work only with AIRJACK driver 00157 if (config.TypeOfCard == AIRJACK_CARD) { 00158 Send_To_All_BSSID_A_Deauth(); 00159 } else { 00160 warning 00161 ("De-authentication is only available with Airjack26 driver\n"); 00162 } 00163 CLEAR_KEYBOARD_BUFFER; 00164 break; 00165 case 'J': 00166 // Activate the Jamming process 00167 // send de-authentication to FF:FF:FF:FF:FF:FF when a beacon is detected 00168 if (config.TypeOfCard == AIRJACK_CARD) { 00169 if (config.JammingNow == TRUE) { 00170 config.JammingNow = FALSE; 00171 } else { 00172 config.JammingNow = TRUE; 00173 } 00174 } else { 00175 warning("Jamming is only available with Airjack26 driver\n"); 00176 } 00177 CLEAR_KEYBOARD_BUFFER; 00178 break; 00179 case 'c': // a 4 key option 00180 case 'j': // a 2 key option 00181 case 'v': // a 2 key option 00182 case 'n': // a 2 key option 00183 break; 00184 default: // the user hit the keyboard, but don't know what he do 00185 CLEAR_KEYBOARD_BUFFER; 00186 break; 00187 } 00188 break; 00189 case 2: 00190 switch (keystring[0]) { 00191 case 'c': 00192 break; 00193 case 'j': 00194 switch (keystring[1]) { 00195 case '+': // Go to next channel hop 00196 if (config.ChannelHop < HOP_MAX) 00197 config.ChannelHop++; 00198 break; 00199 case '-': // Go to previous channel hop 00200 if (config.ChannelHop > HOP_MIN) 00201 config.ChannelHop--; 00202 break; 00203 default: 00204 break; 00205 } 00206 debug(2, "config.ChannelHop = %d\n", config.ChannelHop); 00207 CLEAR_KEYBOARD_BUFFER; 00208 break; 00209 case 'v': 00210 switch (keystring[1]) { 00211 case '+': // Be more verbose 00212 if (config.DebugLevel < MAX_DEBUG_LEVEL) 00213 config.DebugLevel++; 00214 break; 00215 case '-': // Be less verbose 00216 if (config.DebugLevel > 0) 00217 config.DebugLevel--; 00218 break; 00219 default: 00220 CLEAR_KEYBOARD_BUFFER; 00221 break; 00222 } 00223 debug(1, "DebugLevel=%d\n", config.DebugLevel); 00224 CLEAR_KEYBOARD_BUFFER; 00225 keyindex = 0; 00226 memset(keystring, 0, KEYBOARD_BUFFER); 00227 break; 00228 case 'n': 00229 switch (keystring[1]) { 00230 case 'a': 00231 SWITCH_BIT(config.DoNotDisplay, DISPLAY_ACK_BIT); 00232 debug(1, "Switch display of ACK\n"); 00233 break; 00234 case 'b': 00235 SWITCH_BIT(config.DoNotDisplay, DISPLAY_BEACON_BIT); 00236 debug(1, "Switch display of BEACON\n"); 00237 break; 00238 case 'c': 00239 SWITCH_BIT(config.DoNotDisplay, DISPLAY_CONTROL_BIT); 00240 debug(1, "Switch display of CONTROL\n"); 00241 break; 00242 case 'd': 00243 SWITCH_BIT(config.DoNotDisplay, DISPLAY_DATA_BIT); 00244 debug(1, "Switch display of DATA\n"); 00245 break; 00246 case 'p': 00247 SWITCH_BIT(config.DoNotDisplay, DISPLAY_PROBE_BIT); 00248 debug(1, "Switch display of PROBE REQ/RES\n"); 00249 break; 00250 case 's': 00251 SWITCH_BIT(config.DoNotDisplay, DISPLAY_STATION_BIT); 00252 debug(1, "Switch display of STATION\n"); 00253 ClearPanel(); 00254 break; 00255 default: 00256 CLEAR_KEYBOARD_BUFFER; 00257 break; 00258 } 00259 CLEAR_KEYBOARD_BUFFER; 00260 break; 00261 default: 00262 CLEAR_KEYBOARD_BUFFER; 00263 break; 00264 } 00265 break; 00266 case 3: 00267 break; 00268 case 4: 00269 // Sequence : C??C 00270 // Change channel to a fixed channel 00271 if (keystring[0] == 'c' && keystring[3] == 'c') { 00272 keystring[3] = '\0'; 00273 00274 if (keystring[1] == '0') 00275 chan = atoi(keystring + 2); 00276 else 00277 chan = atoi(keystring + 1); 00278 00279 if (chan >= 0 && chan <= CHANNEL_MAX) { 00280 ret = selectChannel(config.devname, chan); 00281 if (ret == 0) { 00282 config.SingleChannel = (UINT8) chan; // All is OK 00283 } else { 00284 selectChannel(config.devname, config.SingleChannel); // PB, so go back previous channel 00285 warning("Channel %d is forbidden (%d)\n", chan, ret); 00286 } 00287 memset(keystring, 0, KEYBOARD_BUFFER); 00288 keyindex = 0; 00289 } 00290 debug(2, "Scan only channel %d\n", config.SingleChannel); 00291 } else { 00292 CLEAR_KEYBOARD_BUFFER; 00293 } 00294 break; 00295 default: // the user hit the keyboard, but don't know what he do 00296 CLEAR_KEYBOARD_BUFFER; // So we think that it was sleeping ;-) and forget ... 00297 break; 00298 } 00299 }
void check_keys | ( | ) |
void stop_signal | ( | void | ) |
Signal Handler
Definition at line 77 of file scanner.c.
References EXIT_BY_CTRLC, screen_mutex, stop_sniffing, and warning().
Referenced by main().
00078 { 00079 // We don't need to stop, if we know that we will stop 00080 if (!stop_sniffing) { 00081 #ifdef WITH_THREAD 00082 // Clean and Force STOP the thread 00083 pthread_mutex_unlock(&screen_mutex); 00084 //pthread_kill( &thread_ChgChan, (int) 1); 00085 pthread_mutex_destroy(&screen_mutex); 00086 #endif 00087 warning("Received CTRL-C - sniffing aborted\n\n"); 00088 stop_sniffing = EXIT_BY_CTRLC; 00089 } 00090 }
void ChangeChannel_th | ( | void * | ptr1 | ) |
Definition at line 112 of file scanner.c.
References ConfigStruct::ChannelHop, debug, EXIT_PB_WITH_CHANNEL_HOP, NextChannel(), ConfigStruct::SingleChannel, stop_sniffing, ConfigStruct::TimeToSleepBeforeChangeChannel, and warning().
Referenced by main().
00113 { 00114 struct timeb binary_now, TimeScann; 00115 char *devname; 00116 register UINT32 TTSBCC; 00117 register UINT32 TTSBCC100; 00118 00119 //struct timespec delay; 00120 00121 ftime(&TimeScann); 00122 devname = (char *) ptr1; 00123 00124 while (stop_sniffing == 0) { 00125 /*** Time trigger for change channel ***/ 00126 TTSBCC = config.TimeToSleepBeforeChangeChannel; 00127 TTSBCC100 = config.TimeToSleepBeforeChangeChannel * 100; 00128 // Save time, so we change channel only when it's time 00129 ftime(&binary_now); 00130 // is it time to change channel ? 00131 if (config.SingleChannel == 0 && 00132 ((binary_now.time - TimeScann.time) * 1000) + 00133 ((binary_now.millitm - TimeScann.millitm)) >= 00134 (signed long) TTSBCC) { 00135 /* it's time to change Channel */ 00136 ftime(&TimeScann); 00137 if (NextChannel(devname, config.ChannelHop)) { 00138 stop_sniffing = EXIT_PB_WITH_CHANNEL_HOP; 00139 debug(2, "devname = %s, ChannelHop=%d\n", 00140 devname, config.ChannelHop); 00141 warning("Can't change Channel\n"); 00142 break; // Exit while (stop_sniffing == 0) 00143 } 00144 } 00145 usleep(TTSBCC100); 00146 } 00147 pthread_exit(0); 00148 }
int main | ( | int | argc, | |
char ** | argv | |||
) |
Write it also on file if wanted
A little mark for better view :)
Exit from curses environment
Close file if needed, it's better clean
Close file if needed, it's better clean
Close RaxSocket
put card in a normal state
Write the summary
And the .dot file also
Definition at line 154 of file scanner.c.
References BoolToStaAp(), BoolToWepNoWep(), ScanResult_t::BssId, Bye(), ChangeChannel_th(), ScanResult_t::Channel, ConfigStruct::ChannelHop, ChannelToStr(), check_keys(), check_keys_th(), ConfigStruct::CheckScreenSize, CISCO_CARD, CISCO_CVS_CARD, closePacket(), CursesIsInUse, ConfigStruct::DateFormat, debug, DEBUG_POINT, ConfigStruct::DebugLevel, ScanResult_t::DestMac, ConfigStruct::devname, ConfigStruct::devname2, DispConf(), DO_NOT_DISPLAY_ACK, DO_NOT_DISPLAY_BEACON, DO_NOT_DISPLAY_CONTROL, DO_NOT_DISPLAY_DATA, DO_NOT_DISPLAY_PROBE, DumpHexPaquets(), EndCurses(), ERROR_CANT_OPEN_FILE, ERROR_NOT_ROOT, ERROR_PCAP_CANT_OPEN, ERROR_SIG_HANDLER, ERROR_THREAD_CANT_INIT, ERROR_UNKNOWN_INTERFACE, EXIT_CANT_SAVE_DATA, EXIT_MAX_PACKET_REACHED, EXIT_PB_WITH_CHANNEL_HOP, FALSE, fatal(), GET_TYPE_BIT_AP, GET_TYPE_BIT_FROMDS, getPacket(), ScanResult_t::hasWep, ScanResult_t::hasWPA, IDS(), ConfigStruct::IDS_is_ON, ids_warning, InitConfiguration(), InitScreen(), Statistics_t::INVLD, LogWriteDOT(), LogWriteHisto(), LogWriteReport(), MAX_BUFFER_SIZE, MAX_NUMBER_OF_DETECTED_CLIENT, ConfigStruct::MaxPacket, Statistics_t::MaxSignal, NextChannel(), NO_ERROR, ScanResult_t::Noise, openCard(), openPacket(), ConfigStruct::OutDotFileName, ConfigStruct::OutDumpFileName, ConfigStruct::OutFileName, Statistics_t::Packets, Panel_WND, ParseCommandLine(), PCAP_VIRTUAL_CARD, processPacket(), ScanResult_t::Rate, RateToString(), RealTime_WND, RefreshRealTime_WND(), RefreshRealTime_WND_th(), ROW_WND_PANEL, ScanResult_t::SChannel, screen_mutex, selectChannel(), shutCard(), ScanResult_t::Signal, ConfigStruct::SingleChannel, ScanResult_t::SrcMac, ScanResult_t::SSID, stop_signal(), stop_sniffing, SubTypeOfClientToString(), Sum_WND, thread_checkkey, thread_ChgChan, thread_RefreshRTW, ConfigStruct::TimeToSleepBeforeChangeChannel, TRUE, ConfigStruct::TypeOfCard, ScanResult_t::TypeOfClient, TypeOfClientToString(), ScanResult_t::TypeOfPacket, ScanResult_t::TypeSubtype, warning(), WIFISCANNER_VERSION, WLAN_FSTYPE_PROBEREQ, WLAN_FTYPE_MGMT, WLAN_GET_FC_FSTYPE, WLAN_GET_FC_FTYPE, wlan_header, WritePanel(), and WriteSummary().
00155 { 00156 int recvlen; // Size of packet received 00157 00158 //int MaxPacketPerChannel; // Number of packet received before the next channel is select 00159 struct tm *ascii_now = NULL; // The timestamp in ASCII (human readable) 00160 struct timeb binary_now; 00161 UINT8 msgbuf[MAX_BUFFER_SIZE]; // packet container 00162 p80211_caphdr_t wlan_header; 00163 00164 #ifdef WITHOUT_THREAD 00165 struct timeb TimeScann; 00166 #endif 00167 #ifdef WITH_WIRETAP 00168 struct wtap_pkthdr packet_hdr_info; // pointer to the header of wtap packet 00169 int wtap_error; 00170 wtap_dumper *dump_file = NULL; // pointer to the file used to save pcap data 00171 #else 00172 char *dump_file = NULL; 00173 #endif 00174 UINT64 CatchPacket = 0; 00175 char PacketStatus[256]; 00176 FILE *OutFile = NULL; 00177 FILE *OutDumpFile = NULL; 00178 FILE *OutDotFile = NULL; 00179 UINT8 GotItOne = FALSE; 00180 UINT8 ids_warning = (UINT8) 0; 00181 char strChannel[8]; 00182 UINT8 ActifChannel = 0; 00183 int ret; 00184 00185 00186 // Wifiscanner Info Banner 00187 fprintf(stderr, 00188 "WifiScanner v%s (c) 2002-2008 Hervé Schauer Consultants (", 00189 WIFISCANNER_VERSION); 00190 fprintf(stderr, "Jerome.Poggi@hsc-labs.com)\n\n"); 00191 00192 // Configuration declaration 00193 InitConfiguration(&config); 00194 00195 /* parse command line */ 00196 ParseCommandLine(argc, argv, &config); 00197 00198 // Root permissions test 00199 if (getuid() != 0) { 00200 warning 00201 ("Hum hum, you seem to be not have the root capabilities...\n" 00202 "wifiscanner -h for help\n" 00203 "Try to obtain root capabilities and re-run me :-)\n"); 00204 Bye(ERROR_NOT_ROOT); 00205 } 00206 00207 // Display the configuration 00208 DispConf(&config); 00209 00210 // For information 00211 debug(3, "Size of ClientInfo_t struct : %6d bytes\n", 00212 sizeof(ClientInfo_t)); 00213 debug(3, "Size of ClientInfo_t array : %6d bytes\n", 00214 (sizeof(ClientInfo_t) * MAX_NUMBER_OF_DETECTED_CLIENT)); 00215 00216 // We try to interract with the card, if it's not possible we exit 00217 if (openCard(config.devname)) { 00218 fatal(ERROR_UNKNOWN_INTERFACE, "The interface can not be found or initialize\n"); 00219 } 00220 // Sanity check 00221 if (config.OutFileName) { 00222 if ((OutFile = fopen(config.OutFileName, "a")) == NULL) { 00223 fatal(ERROR_CANT_OPEN_FILE, "Cant open outfile %s for writing\n", config.OutFileName); 00224 } 00225 } 00226 #ifdef WITH_WIRETAP 00227 // Sanity check 00228 if (config.OutDumpFileName) { 00229 dump_file = malloc(sizeof dump_file); 00230 dump_file = 00231 wtap_dump_open(config.OutDumpFileName, WTAP_FILE_PCAP, 00232 WTAP_ENCAP_IEEE_802_11, 2344, FALSE, &wtap_error); 00233 //WTAP_ENCAP_ETHERNET, 2344, FALSE, &wtap_error); 00234 if (!dump_file) { 00235 fatal(ERROR_CANT_OPEN_FILE, "Cannot make the dump file!\n"); 00236 } 00237 debug(3, "dump_file pointer is : %08X\n", dump_file); 00238 } 00239 #endif 00240 00241 // Install interrupt handler... 00242 fprintf(stderr, "Install interrupt handler...\n"); 00243 if ((signal(SIGINT, (__sighandler_t) stop_signal) == SIG_ERR) || 00244 (signal(SIGTERM, (__sighandler_t) stop_signal) == SIG_ERR) || 00245 (signal(SIGHUP, (__sighandler_t) stop_signal) == SIG_ERR)) { 00246 fatal(ERROR_SIG_HANDLER ,"AAAARRRGGG ! Can't install the SIGHUP handler !\n"); 00247 } 00248 00249 // Open PCAP File 00250 fprintf(stderr, "Open the packet capture interface (pcap)\n"); 00251 if (config.TypeOfCard == CISCO_CVS_CARD) { 00252 ret = openPacket(config.devname2); 00253 if (ret != NO_ERROR) { 00254 fprintf(stderr, "Can't open pcap %s device2 (err: %d = %s)\n", 00255 config.devname2, errno, strerror(errno)); 00256 Bye(ERROR_PCAP_CANT_OPEN); 00257 } 00258 } else { 00259 if (config.TypeOfCard != PCAP_VIRTUAL_CARD) { 00260 ret = openPacket(config.devname); 00261 debug(3, " openPacket(config.devname) = %d\n", ret); 00262 if (ret != NO_ERROR) { 00263 fprintf(stderr, "Can't open pcap %s device (err: %d = %s)\n", 00264 config.devname, errno, strerror(errno)); 00265 #ifdef WITH_WIRETAP 00266 //wtap_dump_close(dump_file, &wtap_error); 00267 #endif 00268 Bye(ERROR_PCAP_CANT_OPEN); 00269 } 00270 } 00271 } 00272 00273 fprintf(stderr, "Beginning scan of the 802.11b networks...\n"); 00274 fprintf(stderr, "Use CTRL-C or Q to stop sniffing\n"); 00275 00276 #ifdef HAVE_LIBNCURSES 00277 // Do a pause, so debug info can be read 00278 if (config.DebugLevel >= 1) { 00279 debug(1, "Wait 5 seconds, so debug info can be read\n"); 00280 sleep(5); // Sleep 5 seconds, so debug info can be read 00281 } 00282 /* Initialisation of NCURSES */ 00283 CursesIsInUse = TRUE; 00284 InitScreen(config.CheckScreenSize); 00285 if (config.IDS_is_ON == TRUE) 00286 mvwprintw(Sum_WND, 17, 3, "IDS is ON "); 00287 #else 00288 if (config.IDS_is_ON == TRUE) 00289 fprintf(stderr, "IDS is ON"); 00290 #endif 00291 00292 /*** 00293 * Change my Priority and put all keyboard input to trash 00294 ***/ 00295 00296 (void) setvbuf(stdin, NULL, _IONBF, 0); // Input go to trash :-) 00297 (void) setpriority(PRIO_PROCESS, 0, -15); // take more CPU than normal 00298 00299 /*** 00300 * Initialisation of the selected channel in single channel scan 00301 ***/ 00302 if (config.SingleChannel && 00303 !selectChannel(config.devname, config.SingleChannel)) { 00304 //stop_sniffing = EXIT_PB_WITH_CHANNEL_INIT; 00305 warning("Can't initialize Channel number %d !\n", 00306 config.SingleChannel); 00307 //sleep (5); 00308 } 00309 00310 00311 00312 /* 00313 * We install our threads here 00314 */ 00315 #ifdef WITH_THREAD 00316 // Thread for changing channel 00317 // --------------------------- 00318 if ((config.TypeOfCard != CISCO_CVS_CARD) 00319 && (config.TypeOfCard != CISCO_CARD)) { 00320 ret = 00321 pthread_create(&thread_ChgChan, NULL, (void *) &ChangeChannel_th, 00322 (void *) config.devname); 00323 if (ret < 0) 00324 fatal(ERROR_THREAD_CANT_INIT, "Boom ! Thread to change channel cannot create (err:%d)\n", 00325 ret); 00326 } 00327 // Thread to refresh screen only one time per second 00328 // ------------------------------------------------- 00329 if (config.DebugLevel < 2) { 00330 ret = 00331 pthread_create(&thread_RefreshRTW, NULL, 00332 (void *) &RefreshRealTime_WND_th, (void *) NULL); 00333 if (ret < 0) 00334 fatal(ERROR_THREAD_CANT_INIT, "Boom ! Thread to refresh screen cannot create (err:%d)\n", 00335 ret); 00336 } 00337 // Thread to check keyboard 00338 // ------------------------ 00339 ret = 00340 pthread_create(&thread_checkkey, NULL, (void *) &check_keys_th, 00341 (void *) config.devname); 00342 if (ret < 0) 00343 fatal(ERROR_THREAD_CANT_INIT, "Boom ! Thread to manage keyboard cannot create (err:%d)\n", 00344 ret); 00345 #else 00346 ftime(&TimeScann); 00347 #endif 00348 00349 /***** 00350 This is the linear and threaded scheduler 00351 TODO : To convert in more thread (Work in progress) :-) 00352 TODO : It's better to be ONLY threaded 00353 ******/ 00354 while (stop_sniffing == 0) { 00355 00356 // debug (3, "## Begin of loop ## dump_file pointer is : %08X\n", dump_file); 00357 #ifdef WITHOUT_THREAD 00358 check_keys(); 00359 /*** Time trigger for change channel ***/ 00360 // Save time, so we change channel only when it's time 00361 ftime(&binary_now); 00362 // is it time to change channel ? 00363 if (((binary_now.time - TimeScann.time) * 1000) + 00364 (binary_now.millitm - TimeScann.millitm) >= 00365 (config.TimeToSleepBeforeChangeChannel)) { 00366 /* it's time to change Channel */ 00367 if (!config.SingleChannel) { 00368 ftime(&TimeScann); 00369 if (NextChannel(config.devname, config.ChannelHop) != NO_ERROR) { 00370 stop_sniffing = EXIT_PB_WITH_CHANNEL_HOP; 00371 debug(0, "Can't change Channel\n"); 00372 break; // Exit while (stop_sniffing == 0) 00373 } 00374 } 00375 } 00376 #endif 00377 00378 /*** Get packet process ***/ 00379 memset(msgbuf, 0, MAX_BUFFER_SIZE); 00380 // recvlen = getPacket(msgbuf, MAX_BUFFER_SIZE, TIMEOUT_TRY_TO_READ_PAQUET); 00381 recvlen = getPacket(&wlan_header, msgbuf, MAX_BUFFER_SIZE); 00382 00383 if (recvlen > 0) { 00384 // Get it one ? Yes ! so analyse it 00385 Stats.Packets++; 00386 GotItOne = TRUE; 00387 // Save the hardware channel before the washing machine 00388 ActifChannel = Res.SChannel; 00389 memset(&Res, 0, sizeof(Res)); 00390 Res.SChannel = ActifChannel; 00391 // Print the packet number and size 00392 debug(2, "Packet number : %ld\n", CatchPacket); 00393 debug(2, "recvlen = %X\n", recvlen); 00394 00395 // Just an Hexdump packet 00396 if (config.DebugLevel >= 2) { 00397 DumpHexPaquets(RealTime_WND, msgbuf, recvlen); 00398 //wrefresh(RealTime_WND); 00399 } 00400 /* END DEBUG */ 00401 00402 #ifdef WITH_WIRETAP 00403 /*** Write DATA to DumpFile ***/ 00404 if (config.OutDumpFileName) { 00405 /* 00406 * Setup Wiretap packet header 00407 */ 00408 gettimeofday(&packet_hdr_info.ts, NULL); 00409 packet_hdr_info.caplen = recvlen; 00410 packet_hdr_info.len = recvlen; 00411 packet_hdr_info.pkt_encap = WTAP_ENCAP_IEEE_802_11; 00412 00413 DEBUG_POINT; 00414 00415 /* 00416 * Now we can save the frame to the capture file 00417 */ 00418 if (!wtap_dump 00419 (dump_file, &packet_hdr_info, NULL, &msgbuf, &wtap_error)) { 00420 stop_sniffing = EXIT_CANT_SAVE_DATA; 00421 warning("Can't save DATA\n"); 00422 goto NoPacketIsCatched; 00423 } 00424 } 00425 #endif 00426 00427 /* 00428 * Analyse Data and Write Result 00429 */ 00430 if (processPacket(&wlan_header, msgbuf, recvlen)) { 00431 // Define how and what we display for channel 00432 ChannelToStr(strChannel, Res.Channel, Res.SChannel); 00433 //debug (0, "SSID = '%s'\n", Res.SSID); 00434 00435 // Different date format. 00436 ftime(&binary_now); 00437 if (config.DateFormat == 0) { 00438 snprintf(PacketStatus, 255, 00439 "%d.%03d,\"%s\",%s,%s,%s,%03d,%03d,%s,%s,%s,%s,%s,%s,%s\n", 00440 (int) binary_now.time, 00441 binary_now.millitm, 00442 Res.SSID, strChannel, 00443 BoolToWepNoWep(Res.hasWep, Res.hasWPA), 00444 BoolToStaAp(GET_TYPE_BIT_AP(Res.TypeOfClient), GET_TYPE_BIT_FROMDS(Res.TypeOfClient)), 00445 Res.Signal, Res.Noise, 00446 Res.DestMac, Res.SrcMac, 00447 Res.BssId, 00448 RateToString(Res.Rate), 00449 TypeOfClientToString(Res.TypeOfClient), 00450 SubTypeOfClientToString 00451 (Res.TypeOfClient), Res.TypeOfPacket); 00452 } else { 00453 ascii_now = localtime(&binary_now.time); 00454 snprintf(PacketStatus, 255, 00455 "%02d/%02d/%04d %02d:%02d:%02d.%03d," 00456 "\"%s\",%s,%s,%s,%03d,%03d,%s,%s,%s,%s,%s,%s,%s\n", 00457 ascii_now->tm_mon + 1, 00458 ascii_now->tm_mday, 00459 ascii_now->tm_year + 1900, 00460 ascii_now->tm_hour, 00461 ascii_now->tm_min, 00462 (binary_now.millitm == 1000) ? 00463 (ascii_now->tm_sec + 1) : ascii_now->tm_sec, 00464 (binary_now.millitm == 1000) ? 00465 0 : binary_now.millitm, 00466 Res.SSID, strChannel, 00467 BoolToWepNoWep(Res.hasWep, Res.hasWPA), 00468 BoolToStaAp(GET_TYPE_BIT_AP(Res.TypeOfClient), GET_TYPE_BIT_FROMDS(Res.TypeOfClient)), 00469 Res.Signal, Res.Noise, Res.DestMac, Res.SrcMac, 00470 Res.BssId, RateToString(Res.Rate), 00471 TypeOfClientToString(Res.TypeOfClient), 00472 SubTypeOfClientToString(Res.TypeOfClient), 00473 Res.TypeOfPacket); 00474 } 00475 00476 // Save the maximum strength of signal for print an hitogram 00477 // Do it only if it not a Control packet 00478 if (((WLAN_GET_FC_FTYPE(Res.TypeSubtype) == WLAN_FTYPE_MGMT) && 00479 (WLAN_GET_FC_FSTYPE(Res.TypeSubtype) == WLAN_FSTYPE_PROBEREQ) 00480 ) 00481 ) { 00482 debug(3, "PROBEREQ no power was save\n"); 00483 } else { 00484 if (Stats.MaxSignal[ActifChannel - 1] < Res.Signal) { 00485 Stats.MaxSignal[ActifChannel - 1] = Res.Signal; 00486 } 00487 } 00488 00489 // SWITCH : DISPLAY or NOT a sort of Packet 00490 if (!((DO_NOT_DISPLAY_ACK) 00491 || (DO_NOT_DISPLAY_BEACON) 00492 || (DO_NOT_DISPLAY_CONTROL) 00493 || (DO_NOT_DISPLAY_DATA) 00494 || (DO_NOT_DISPLAY_PROBE))) { 00495 #ifdef HAVE_LIBNCURSES 00496 wprintw(RealTime_WND, "%s", PacketStatus); 00497 #else 00498 fprintf(stdout, "%s", PacketStatus); 00499 #endif //#ifdef HAVE_LIBNCURSES 00500 } 00502 if (OutFile) { 00503 fprintf(OutFile, "%s", PacketStatus); 00504 fflush(OutFile); 00505 } 00507 debug(1, "--- END OF PACKET PROCESSING ---\n"); 00508 #ifdef HAVE_LIBNCURSES 00509 WritePanel(TRUE); 00510 //RefreshRealTime_WND(GotItOne); 00511 #else 00512 fflush(stdout); 00513 #endif // #ifdef HAVE_LIBNCURSES 00514 } else { /* if (processPacket */ 00515 /* Packet is not analysed */ 00516 // Init of time 00517 //ftime (&binary_now); 00518 00519 if (Res.TypeOfPacket != NULL) { 00520 if (config.DateFormat == 0) { 00521 snprintf(PacketStatus, 255, 00522 "%d.%03d,%s\n", 00523 (int) binary_now. 00524 time, binary_now.millitm, Res.TypeOfPacket); 00525 } else { 00526 ascii_now = localtime(&binary_now.time); 00527 snprintf(PacketStatus, 255, 00528 "%02d/%02d/%04d %02d:%02d:%02d.%03d,%s\n", 00529 ascii_now->tm_mon + 1, 00530 ascii_now->tm_mday, 00531 ascii_now->tm_year + 1900, 00532 ascii_now->tm_hour, 00533 ascii_now->tm_min, 00534 ascii_now->tm_sec, 00535 binary_now.millitm, Res.TypeOfPacket); 00536 } 00537 00538 #ifdef HAVE_LIBNCURSES 00539 wprintw(RealTime_WND, "%s", PacketStatus); 00540 WritePanel(FALSE); 00541 warning("Bad Packet !\n"); 00542 // DumpHexPaquets(RealTime_WND, msgbuf, recvlen); 00543 //RefreshRealTime_WND(GotItOne); 00544 #else 00545 fprintf(stdout, "%s\n", PacketStatus); 00546 #endif // #ifdef HAVE_LIBNCURSES 00547 00548 // Write it also on file if wanted 00549 if (OutFile) { 00550 fprintf(OutFile, "%s", PacketStatus); 00551 } 00552 } 00553 } 00554 // Exit if we reach the maximum of packets wanted 00555 ++CatchPacket; 00556 if ((config.MaxPacket != 0) 00557 && (CatchPacket >= (config.MaxPacket + Stats.INVLD))) { 00558 stop_sniffing = EXIT_MAX_PACKET_REACHED; // Exit the principal loop 00559 warning("Max packets reached\n"); 00560 } 00561 } else { 00562 // No packet ? so sleep and wait 00563 /* An another solution is to used "blocking" IO */ 00564 //if (config.SingleChannel) 00565 //usleep (TIMEOUT_TRY_TO_READ_PAQUET); 00566 usleep(config.TimeToSleepBeforeChangeChannel * 10); 00567 } 00568 NoPacketIsCatched: 00569 00570 if (GotItOne) { 00571 if ((config.IDS_is_ON == TRUE) && ((ids_warning = IDS()) != 0)) { 00572 ascii_now = localtime(&binary_now.time); 00573 #ifdef HAVE_LIBNCURSES 00574 if (config.DateFormat == 0) { 00575 mvwprintw(Panel_WND, ROW_WND_PANEL - 1, 24, "IDS WARNING (%d)", 00576 (int) binary_now.time); 00577 } else { 00578 mvwprintw(Panel_WND, ROW_WND_PANEL - 1, 24, 00579 "IDS WARNING (%02d/%02d/%04d %02d:%02d:%02d)", 00580 ascii_now->tm_mon + 1, ascii_now->tm_mday, 00581 ascii_now->tm_year + 1900, ascii_now->tm_hour, 00582 ascii_now->tm_min, ascii_now->tm_sec); 00583 } 00584 #else 00585 if (config.DateFormat == 0) { 00586 fprintf(stderr, "IDS WARNING (%d)", (int) binary_now.time); 00587 } else { 00588 fprintf(stderr, 00589 "IDS WARNING (%02d/%02d/%04d %02d:%02d:%02d)", 00590 ascii_now->tm_mon + 1, 00591 ascii_now->tm_mday, 00592 ascii_now->tm_year + 1900, 00593 ascii_now->tm_hour, 00594 ascii_now->tm_min, ascii_now->tm_sec); 00595 } 00596 #endif 00597 } 00598 } 00599 #ifdef HAVE_LIBNCURSES 00600 WriteSummary(); 00601 RefreshRealTime_WND(GotItOne); 00602 #endif 00603 // For refreshing screen only one time per second 00604 GotItOne = FALSE; 00605 } /* while still sniffing */ 00606 00607 #ifdef WITH_THREAD 00608 // Wait thread to exit 00609 if (!config.SingleChannel) { // TODO check if thread_ChgChan if is null and kill thread if not 00610 void *ret; 00611 00612 warning("Waiting thread_ChgChan to exit..."); 00613 (void) pthread_join(thread_ChgChan, &ret); 00614 warning("OK\n"); 00615 } 00616 if (config.DebugLevel < 2) { 00617 void *ret; 00618 00619 warning("Waiting thread_RefreshRTW to exit..."); 00620 (void) pthread_join(thread_RefreshRTW, &ret); 00621 warning("OK\n"); 00622 } 00623 // Destroy MUTEX 00624 pthread_mutex_destroy(&screen_mutex); 00625 #endif 00626 if (config.DebugLevel > 0) { 00627 warning("Wait 5 seconds before exit...\n"); 00628 sleep(5); 00629 } 00630 00631 EndCurses(); 00632 00633 if (OutFile) { 00634 fclose(OutFile); 00635 } 00636 #ifdef WITH_WIRETAP 00637 if (OutDumpFile) { 00638 wtap_dump_close(dump_file, &wtap_error); 00639 free(dump_file); 00640 } 00641 #endif 00642 00643 closePacket(); 00644 shutCard(config.devname); 00645 00646 LogWriteReport(); 00647 00648 if (config.OutDotFileName) { 00649 if ((OutDotFile = fopen(config.OutDotFileName, "w")) == NULL) { 00650 fatal(ERROR_CANT_OPEN_FILE, "Cant open outfile %s for writing\n", config.OutDotFileName); 00651 } 00652 LogWriteDOT(OutDotFile); 00653 fclose(OutDotFile); 00654 } 00655 LogWriteHisto(); 00656 00657 debug(3, "Stop Sniffing = %d\n", stop_sniffing); 00658 Bye(stop_sniffing); 00659 }
Definition at line 60 of file scanner.c.
Referenced by analyseACK(), analyseBeacon(), analyseCTS(), analyseData(), analyseMGMT(), analyseProbeRep(), analyseProbeReq(), analysePSPOLL(), analyseRTS(), dataIsCrypted(), processPacket(), ProcessTagBits(), and UpdateOtherInformation().
WINDOW* Title_WND |
WINDOW * Panel_WND |
Definition at line 61 of file scanner.c.
Referenced by ClearPanel(), InitScreen(), main(), RefreshAllWND(), RefreshRealTime_WND(), RefreshRealTime_WND_th(), and WritePanel().
WINDOW * Sum_WND |
Definition at line 61 of file scanner.c.
Referenced by check_keys_th(), InitScreen(), main(), PrintScaleChannel(), RefreshAllWND(), and WriteSummary().
WINDOW * RealTime_WND |
Definition at line 61 of file scanner.c.
Referenced by analyseBeacon(), debug(), debugTS(), FillRadioData(), getPacketIPW(), getPacketPCAP(), InitScreen(), main(), RefreshAllWND(), RefreshRealTime_WND(), RefreshRealTime_WND_th(), warning(), and warning_if_error().
UINT8 CursesIsInUse = (UINT8) 0 |
Definition at line 63 of file scanner.c.
Referenced by debug(), debugTS(), EndCurses(), fatal(), main(), warning(), and warning_if_error().
pthread_mutex_t screen_mutex = PTHREAD_MUTEX_INITIALIZER |
MUTEX for lock screen, so only one func write to it at the same time.
Definition at line 67 of file scanner.c.
Referenced by check_keys_th(), ClearPanel(), debug(), debugTS(), DumpHexPaquets(), main(), parse_keystring(), PrintScaleChannel(), RefreshAllWND(), RefreshRealTime_WND_th(), stop_signal(), warning(), warning_if_error(), WritePanel(), and WriteSummary().
pthread_t thread_ChgChan |
pthread_t thread_RefreshRTW |
pthread_t thread_checkkey |
UINT8 stop_sniffing = (UINT8) 0 |
Definition at line 69 of file scanner.c.
Referenced by ChangeChannel_th(), check_keys_th(), main(), parse_keystring(), RefreshRealTime_WND_th(), and stop_signal().