00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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;
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
00080 if (!stop_sniffing) {
00081 #ifdef WITH_THREAD
00082
00083 pthread_mutex_unlock(&screen_mutex);
00084
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
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
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
00120
00121 ftime(&TimeScann);
00122 devname = (char *) ptr1;
00123
00124 while (stop_sniffing == 0) {
00125
00126 TTSBCC = config.TimeToSleepBeforeChangeChannel;
00127 TTSBCC100 = config.TimeToSleepBeforeChangeChannel * 100;
00128
00129 ftime(&binary_now);
00130
00131 if (config.SingleChannel == 0 &&
00132 ((binary_now.time - TimeScann.time) * 1000) +
00133 ((binary_now.millitm - TimeScann.millitm)) >=
00134 (signed long) TTSBCC) {
00135
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;
00143 }
00144 }
00145 usleep(TTSBCC100);
00146 }
00147 pthread_exit(0);
00148 }
00149 #endif
00150
00151
00152
00153
00154 int main(int argc, char **argv)
00155 {
00156 int recvlen;
00157
00158
00159 struct tm *ascii_now = NULL;
00160 struct timeb binary_now;
00161 UINT8 msgbuf[MAX_BUFFER_SIZE];
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;
00169 int wtap_error;
00170 wtap_dumper *dump_file = NULL;
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
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
00193 InitConfiguration(&config);
00194
00195
00196 ParseCommandLine(argc, argv, &config);
00197
00198
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
00208 DispConf(&config);
00209
00210
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
00217 if (openCard(config.devname)) {
00218 fatal(ERROR_UNKNOWN_INTERFACE, "The interface can not be found or initialize\n");
00219 }
00220
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
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
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
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
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
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
00278 if (config.DebugLevel >= 1) {
00279 debug(1, "Wait 5 seconds, so debug info can be read\n");
00280 sleep(5);
00281 }
00282
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
00294
00295
00296 (void) setvbuf(stdin, NULL, _IONBF, 0);
00297 (void) setpriority(PRIO_PROCESS, 0, -15);
00298
00299
00300
00301
00302 if (config.SingleChannel &&
00303 !selectChannel(config.devname, config.SingleChannel)) {
00304
00305 warning("Can't initialize Channel number %d !\n",
00306 config.SingleChannel);
00307
00308 }
00309
00310
00311
00312
00313
00314
00315 #ifdef WITH_THREAD
00316
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
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
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
00351
00352
00353
00354 while (stop_sniffing == 0) {
00355
00356
00357 #ifdef WITHOUT_THREAD
00358 check_keys();
00359
00360
00361 ftime(&binary_now);
00362
00363 if (((binary_now.time - TimeScann.time) * 1000) +
00364 (binary_now.millitm - TimeScann.millitm) >=
00365 (config.TimeToSleepBeforeChangeChannel)) {
00366
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;
00373 }
00374 }
00375 }
00376 #endif
00377
00378
00379 memset(msgbuf, 0, MAX_BUFFER_SIZE);
00380
00381 recvlen = getPacket(&wlan_header, msgbuf, MAX_BUFFER_SIZE);
00382
00383 if (recvlen > 0) {
00384
00385 Stats.Packets++;
00386 GotItOne = TRUE;
00387
00388 ActifChannel = Res.SChannel;
00389 memset(&Res, 0, sizeof(Res));
00390 Res.SChannel = ActifChannel;
00391
00392 debug(2, "Packet number : %ld\n", CatchPacket);
00393 debug(2, "recvlen = %X\n", recvlen);
00394
00395
00396 if (config.DebugLevel >= 2) {
00397 DumpHexPaquets(RealTime_WND, msgbuf, recvlen);
00398
00399 }
00400
00401
00402 #ifdef WITH_WIRETAP
00403
00404 if (config.OutDumpFileName) {
00405
00406
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
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
00429
00430 if (processPacket(&wlan_header, msgbuf, recvlen)) {
00431
00432 ChannelToStr(strChannel, Res.Channel, Res.SChannel);
00433
00434
00435
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
00477
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
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
00511 #else
00512 fflush(stdout);
00513 #endif // #ifdef HAVE_LIBNCURSES
00514 } else {
00515
00516
00517
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
00543
00544 #else
00545 fprintf(stdout, "%s\n", PacketStatus);
00546 #endif // #ifdef HAVE_LIBNCURSES
00547
00548
00549 if (OutFile) {
00550 fprintf(OutFile, "%s", PacketStatus);
00551 }
00552 }
00553 }
00554
00555 ++CatchPacket;
00556 if ((config.MaxPacket != 0)
00557 && (CatchPacket >= (config.MaxPacket + Stats.INVLD))) {
00558 stop_sniffing = EXIT_MAX_PACKET_REACHED;
00559 warning("Max packets reached\n");
00560 }
00561 } else {
00562
00563
00564
00565
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
00604 GotItOne = FALSE;
00605 }
00606
00607 #ifdef WITH_THREAD
00608
00609 if (!config.SingleChannel) {
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
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 }