#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include "callbacks.h" #include "interface.h" #include "support.h" #include "display.h" #include "capture.h" #include "crack.h" #include "bssidlist.h" #include void reallyQuit(void); #ifndef DLT_PRISM_HEADER #define DLT_PRISM_HEADER 119 #endif #ifndef DLT_AIRONET_HEADER #define DLT_AIRONET_HEADER 120 #endif int scan = 1; int oldscan; int chan = 6; int spinchan = 6; int funcId = 0; int doCapture = 0; pthread_t capThread; int breadth40 = 3; int breadth128 = 2; int quitting = 0; int logfile = 0; char dumpfile[256] = {0}; int cardType = 0; int realized = 0; int readPcapFile = 0; char *cards[] = { "Prism2 (wlan-ng)", "Orinoco (orinoco_cs)", "Other" }; static const int NUM_CARDS = sizeof(cards); GtkCList *theList; GdkEventButton *popupEvent; GtkCheckMenuItem *logFileMenu; char errbuf[PCAP_ERRBUF_SIZE]; void reallyQuit() { doCapture = 0; if (logfile != -1) { close(logfile); } saveOpts(); gtk_main_quit(); } /* Function to open a dialog box displaying the message provided. */ void quick_message(char *title, char *message) { GtkWidget *dialog, *label, *okay_button; /* Create the widgets */ dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(dialog), title); gtk_window_set_modal(GTK_WINDOW(dialog), 1); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area), 10); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), 10); label = gtk_label_new (message); okay_button = gtk_button_new_with_label("Okay"); /* Ensure that the dialog box is destroyed when the user clicks ok. */ gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT(dialog)); gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), okay_button, TRUE, FALSE, 0); /* Add the label, and show everything we've added to the dialog. */ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label); gtk_widget_show_all (dialog); } void on_AirSnortWindow_realize (GtkWidget *widget, gpointer user_data) { theList = (GtkCList*) user_data; if (!funcId) { funcId = gtk_timeout_add( 500, (GtkFunction) update, user_data); } } gboolean on_AirSnortWindow_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) { if (!head) { reallyQuit(); } else { gtk_widget_show_all (create_CloseDlg()); } return TRUE; } void on_load_activate (GtkMenuItem *menuitem, gpointer user_data) { if (doCapture) { quick_message("Error", "Can't load while capture in progress"); return; } gtk_widget_show_all (create_FileLoad()); } void on_save_activate (GtkMenuItem *menuitem, gpointer user_data) { gtk_widget_show_all (create_SaveFile()); } void on_exit_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!head) { reallyQuit(); } else { gtk_widget_show_all (create_CloseDlg()); } } void on_clear_activate (GtkMenuItem *menuitem, gpointer user_data) { on_Clear_clicked(NULL, (gpointer)theList); } void on_about_activate (GtkMenuItem *menuitem, gpointer user_data) { gtk_widget_show_all (create_AboutDlg()); } void on_Start_clicked (GtkButton *button, gpointer user_data) { char cmd[80]; CaptureArg *ca; if (doCapture) return; if (!scan) { chan = spinchan; } if (cardType == PRISM) { sprintf(cmd, "wlanctl-ng %s lnxreq_ifstate ifstate=enable > /dev/null", dev); system(cmd); sprintf(cmd, "ifconfig %s up", dev); system(cmd); } if (setChannel(chan)) { quick_message("Error", "Could not set monitor mode"); return; } doCapture = 1; ca = (CaptureArg*) malloc(sizeof(CaptureArg)); ca->pcap = pcap_open_live(dev, 3000, 1, 0, errbuf); if (ca->pcap) { switch (pcap_datalink(ca->pcap)) { case DLT_PRISM_HEADER: ca->offset = 144; break; case DLT_IEEE802_11: ca->offset = 0; break; case DLT_AIRONET_HEADER: ca->offset = 0; break; default: //COOKED ca->offset = 160; } if (*dumpfile) { ca->dump = pcap_dump_open(ca->pcap, dumpfile); dumpfile[0] = 0; } else { ca->dump = NULL; } pthread_create(&capThread, NULL, capture, ca); } } void on_Stop_clicked (GtkButton *button, gpointer user_data) { doCapture = 0; } void on_freq_changed (GtkEditable *editable, gpointer user_data) { spinchan = gtk_spin_button_get_value_as_int((GtkSpinButton*) editable); if (!scan) { chan = spinchan; if (doCapture) { setChannel(chan); } } } void on_scan_toggled (GtkToggleButton *togglebutton, gpointer user_data) { scan = gtk_toggle_button_get_active(togglebutton); if (!scan) { chan = spinchan; if (doCapture) { setChannel(chan); } } } void on_Clear_clicked (GtkButton *button, gpointer user_data) { gtk_clist_clear((GtkCList*) user_data); clearList(); } void on_DataList_select_row (GtkCList *clist, gint row, gint column, GdkEvent *event, gpointer user_data) { } void myPositionFunc(GtkMenu *menu, int *x, int *y, gpointer data) { popupEvent = (GdkEventButton*) data; *x = popupEvent->x_root; *y = popupEvent->y_root; } gboolean on_DataList_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { if (event->button == 3) { gtk_menu_popup (GTK_MENU(create_ListPopup()), NULL, NULL, myPositionFunc, event, event->button, 0); } return FALSE; } void on_CloseYes_clicked (GtkButton *button, gpointer user_data) { quitting = 1; gtk_widget_show_all (create_SaveFile()); } void on_CloseNo_clicked (GtkButton *button, gpointer user_data) { reallyQuit(); } void loadPacketFile (GtkButton *button, gpointer user_data) { PacketInfo pi; CaptureRec cap; unsigned char bssid[6], sta[] = {0,0,0,0,0,0}; unsigned char dummyPacket[200]; int len; unsigned char slen, chan; char *fname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(user_data)); int fd = open(fname, O_RDONLY); cap.pInfo = π cap.bssid = bssid; cap.sta = sta; pi.raw = dummyPacket; if (fd != -1) { while (read(fd, &len, sizeof(int)) == sizeof(int)) { if (read(fd, bssid, 6) != 6) { } if (len == 0) { //this is name info if (read(fd, &chan, 1) != 1) { } pi.channel = chan & 0x0F; dummyPacket[178] = chan & 0x10 ? 0 : 0x10; if (read(fd, &slen, 1) != 1) { } pi.name = (char*) malloc(slen + 1); if (read(fd, pi.name, slen) != slen) { } pi.name[slen] = 0; addBssid(&cap); } else { pi.channel = 0; pi.pack = (Packet *) malloc(sizeof(Packet)); cap.iv = pi.pack->buf = (unsigned char *) malloc(len - 6); pi.pack->len = len - 6; pi.pack->next = NULL; if (read(fd, pi.pack->buf, len - 6) != (len - 6)) { } addPacket(NULL, &cap, 1); } } close(fd); } } /*********************************************************** format of saved data: For ksample packets: 4 byte integer length of 802.11b data = n+6 (includes bssid) 6 byte bssid n bytes of packet data 3 byte IV n-3 bytes of data w/ 802.11b checksum at the end For sample packets 4 byte integer length = 11 6 byte bssid 5 bytes of packet data 3 byte IV 1 dummy byte = 0 1 byte = first byte of 802.11b data (the 0xAA byte) For AP name information 4 byte integer length = 0 6 byte bssid 1 byte channel number 1 byte length of name = n n byte AP name ************************************************************/ void savePacketData (GtkButton *button, gpointer user_data) { unsigned char first, dummy = 0; Packet *pkt; Sample *samp; BssidList *temp = head; int len, i; unsigned char uchar; char *fname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(user_data)); int fd = open(fname, O_WRONLY | O_CREAT, 0644); if (fd != -1) { for (; temp; temp = temp->next) { if (temp->name) { len = 0; write(fd, &len, sizeof(int)); write(fd, temp->bssid, 6); uchar = temp->channel; // uchar |= temp->usingWep ? 0 : 0x10; write(fd, &uchar, 1); uchar = strlen(temp->name); write(fd, &uchar, 1); write(fd, temp->name, uchar); } if (temp->ap) { for (pkt = temp->ap->pkts; pkt; pkt = pkt->next) { len = pkt->len + 6; write(fd, &len, sizeof(int)); write(fd, temp->bssid, 6); write(fd, pkt->buf, pkt->len); } len = 11; for (i = 0; i < 13; i++) { for (samp = temp->ap->samples[i]; samp; samp = samp->next) { write(fd, &len, sizeof(int)); write(fd, temp->bssid, 6); write(fd, samp->iv, 3); write(fd, &dummy, 1); first = samp->firstByte ^ 0xAA; write(fd, &first, 1); } } } } } close(fd); if (quitting) { reallyQuit(); } } void on_savefile_cancel (GtkButton *button, gpointer user_data) { if (quitting) { reallyQuit(); } } void on_stats_activate (GtkMenuItem *menuitem, gpointer user_data) { //fprintf(stderr, "stats\n"); } void on_delete_activate (GtkMenuItem *menuitem, gpointer user_data) { int row, column, result; //fprintf(stderr, "delete\n"); result = gtk_clist_get_selection_info(theList, popupEvent->x, popupEvent->y, &row, &column); if (result) { //fprintf(stderr, "row = %d, col = %d\n", row, column); } else { // fprintf(stderr, "not found\n"); } } void on_stop_activate (GtkMenuItem *menuitem, gpointer user_data) { //fprintf(stderr, "stop\n"); } void on_gps_activate (GtkMenuItem *menuitem, gpointer user_data) { gtk_widget_show_all (create_GpsDialog()); } void on_GpsOk_clicked (GtkButton *button, gpointer user_data) { } void on_log_activate (GtkMenuItem *menuitem, gpointer user_data) { logFileMenu = GTK_CHECK_MENU_ITEM(menuitem); if (logFileMenu->active) { gtk_widget_show_all (create_LogFile()); } else if (logfile) { //file is open, time to close // close(logfile); // logfile = -1; } } void on_log_ok_clicked (GtkButton *button, gpointer user_data) { //this will only take effect when user clicks start to begin a capture strcpy(dumpfile, gtk_file_selection_get_filename(GTK_FILE_SELECTION(user_data))); } void on_log_cancel_button_clicked (GtkButton *button, gpointer user_data) { gtk_check_menu_item_set_active(logFileMenu, 0); } void on_load_pcap_file_activate (GtkMenuItem *menuitem, gpointer user_data) { if (!doCapture) { gtk_widget_show_all (create_PcapFile()); } else { //can't load while capturing quick_message("Error", "Can't load while capture in progress"); } } void on_pcap_ok_clicked (GtkButton *button, gpointer user_data) { CaptureArg *ca = (CaptureArg*) malloc(sizeof(CaptureArg)); char *fname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(user_data)); ca->pcap = pcap_open_offline(fname, errbuf); if (ca->pcap) { switch (pcap_datalink(ca->pcap)) { case DLT_PRISM_HEADER: ca->offset = 144; break; default: //DLT_IEEE802_11 ca->offset = 0; } ca->dump = NULL; oldscan = scan; scan = 0; doCapture = 1; readPcapFile = 1; pthread_create(&capThread, NULL, capture, ca); } } void on_CardType_changed (GtkEditable *editable, gpointer user_data) { char *ct = gtk_entry_get_text(GTK_ENTRY(editable)); for (cardType = 0; cardType < NUM_CARDS; cardType++) { if (!strcmp(cards[cardType], ct)) break; } if (cardType == OTHER && realized) { //tell user that they must set monitor mode manually quick_message("Notice", "You must place your card into monitor mode\nmanually. Channel scan may not be available"); } } void on_DeviceName_changed (GtkEditable *editable, gpointer user_data) { strcpy(dev, gtk_entry_get_text(GTK_ENTRY(editable))); } void on_breadth40_changed (GtkEditable *editable, gpointer user_data) { breadth40 = gtk_spin_button_get_value_as_int((GtkSpinButton*) editable); } void on_breadth128_changed (GtkEditable *editable, gpointer user_data) { breadth128 = gtk_spin_button_get_value_as_int((GtkSpinButton*) editable); } void on_freq_realize (GtkWidget *widget, gpointer user_data) { gtk_spin_button_set_value((GtkSpinButton*) widget, chan); } void on_CardType_realize (GtkWidget *widget, gpointer user_data) { gtk_entry_set_text (GTK_ENTRY (widget), cards[cardType]); realized = 1; } void on_DeviceName_realize (GtkWidget *widget, gpointer user_data) { gtk_entry_set_text(GTK_ENTRY(widget), dev); } void on_breadth40_realize (GtkWidget *widget, gpointer user_data) { gtk_spin_button_set_value((GtkSpinButton*) widget, breadth40); } void on_breadth128_realize (GtkWidget *widget, gpointer user_data) { gtk_spin_button_set_value((GtkSpinButton*) widget, breadth128); }