scanner.c File Reference

#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>

Include dependency graph for scanner.c:

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


Function Documentation

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 }


Variable Documentation

UINT8 ID[] = "$Id: scanner.c 178 2007-08-11 16:57:24Z poggij $" [static]

Definition at line 53 of file scanner.c.

Definition at line 58 of file scanner.c.

WINDOW* Title_WND

Definition at line 61 of file scanner.c.

Referenced by InitScreen(), and RefreshAllWND().

WINDOW * Panel_WND

WINDOW * Sum_WND

WINDOW * RealTime_WND

Definition at line 62 of file scanner.c.

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

Definition at line 68 of file scanner.c.

Referenced by main().

pthread_t thread_RefreshRTW

Definition at line 68 of file scanner.c.

Referenced by main().

pthread_t thread_checkkey

Definition at line 68 of file scanner.c.

Referenced by main().


Generated on Fri Jul 25 17:11:25 2008 for WifiScanner by  doxygen 1.5.5