scanner.c

Go to the documentation of this file.
00001 /*
00002  * File : scanner.c
00003  * Project : WifiScanner (c) 2002-2004 Hervé Schauer Consultants
00004  * Usage : This utility is written for use with IEEE 802.11 adapters based
00005  * on Intersil's PRISM II chipset (PCMCIA).
00006  * 
00007  * Base code was from prismstumbler Jan Fernquist <Jan.B.Fernquist@telia.com>
00008  * and wlanctl from www.linux-wlan.org
00009  *
00010  * This program is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU General Public License
00012  * as published by the Free Software Foundation; either version 2
00013  * of the License, or (at your option) any later version.
00014  * 
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023  *
00024  */
00025 
00026 /* $Id: scanner.c 178 2007-08-11 16:57:24Z poggij $ */
00027 
00028 #include <include.h>
00029 #include <src/interface.h>
00030 #include <src/driver.h>
00031 #include <src/functions.h>
00032 #include <src/analyse.h>
00033 #include <src/scanner.h>
00034 #include <src/crt_io.h>
00035 #include <src/conversion.h>
00036 #include <src/keyboard.h>
00037 #include <src/errmsg.h>
00038 #ifdef WITH_WIRETAP
00039 #include <wtap.h>
00040 #endif
00041 
00042 
00043 /*
00044 */
00045 void Bye(int ExitCode);
00046 void HelpAndBye(void);
00047 void VersionAndBye(void);
00048 void DispConf(ConfigStruct * config);
00049 
00050 void parse_keystring();
00051 void check_keys();
00052 
00053 static UINT8 ID[] = "$Id: scanner.c 178 2007-08-11 16:57:24Z poggij $";
00054 
00055 /*
00056  * Use globals, ugly ... 
00057  */
00058 ConfigStruct config;
00059 
00060 ScanResult_t Res;
00061 WINDOW *Title_WND, *Panel_WND, *Sum_WND, *RealTime_WND;
00062 Statistics_t Stats;
00063 UINT8 CursesIsInUse = (UINT8) 0;        /* To know if curses environment is in use */
00064 
00065 #ifdef WITH_THREAD
00067 pthread_mutex_t screen_mutex = PTHREAD_MUTEX_INITIALIZER;
00068 pthread_t thread_ChgChan, thread_RefreshRTW, thread_checkkey;
00069 UINT8 stop_sniffing = (UINT8) 0;
00070 #else
00071 static UINT8 stop_sniffing = (UINT8) 0;
00072 #endif
00073 
00077 RETSIGTYPE stop_signal(void)
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 }
00091 
00092 /*
00093  *  Display help text and leave
00094  */
00095 void HelpAndBye(void)
00096 {
00097   fprintf(stderr, "%s", HELPTEXT);
00098   fprintf(stderr, "\nPlease send Bug report to : %s\n\n", WIFISCANNER_BUG);
00099   exit(EXIT_SUCCESS);
00100 }
00101 
00102 // Just exit, not sure this function is usefull
00103 void Bye(int ExitCode)
00104 {
00105   fflush(stdout);
00106   fflush(stderr);
00107   fprintf(stderr, "%s\n", ErrorsMsg[ExitCode]);
00108   exit(ExitCode);
00109 }
00110 
00111 #ifdef WITH_THREAD
00112 void ChangeChannel_th(void *ptr1)
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 }
00149 #endif
00150 
00151 
00152 /******** MAIN ********/
00153 
00154 int main(int argc, char **argv)
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 }

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