int main(int argc, char *argv[]) { inquiry_info *ii = NULL; int i, opt, dev_id, sock, len, flags, max_rsp, num_rsp, lap, timeout = 20; uint8_t extended = 0; uint8_t scan = 0; char ubertooth_device = -1; char *bt_dev = "hci0"; char addr[19] = { 0 }; char name[248] = { 0 }; struct libusb_device_handle *devh = NULL; btbb_piconet *pn; bdaddr_t bdaddr; while ((opt=getopt(argc,argv,"ht:xsb:")) != EOF) { switch(opt) { case 'b': bt_dev = optarg; if (bt_dev == NULL) { perror(optarg); return 1; } break; case 't': timeout = atoi(optarg); break; case 'x': extended = 1; break; case 's': scan = 1; break; case 'h': default: usage(); return 1; } } dev_id = hci_devid(bt_dev); sock = hci_open_dev( dev_id ); if (dev_id < 0 || sock < 0) { perror("opening socket"); return 1; } devh = ubertooth_start(ubertooth_device); if (devh == NULL) { usage(); return 1; } /* Set sweep mode - otherwise AFH map is useless */ cmd_set_channel(devh, 9999); if (scan) { len = 8; max_rsp = 255; flags = IREQ_CACHE_FLUSH; ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info)); num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags); if( num_rsp < 0 ) perror("hci_inquiry"); /* Equivalent to "hcitool scan" */ printf("HCI scan\n"); for (i = 0; i < num_rsp; i++) { ba2str(&(ii+i)->bdaddr, addr); memset(name, 0, sizeof(name)); if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name), name, 0) < 0) strcpy(name, "[unknown]"); printf("%s %s\n", addr, name); } free(ii); } /* Now find hidden piconets with Ubertooth */ printf("\nUbertooth scan\n"); btbb_init_survey(); rx_live(devh, NULL, timeout); ubertooth_stop(devh); while((pn=btbb_next_survey_result()) != NULL) { lap = btbb_piconet_get_lap(pn); if (btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) { lap = btbb_piconet_get_lap(pn); sprintf(addr, "00:00:%02X:%02X:%02X:%02X", btbb_piconet_get_uap(pn), (lap >> 16) & 0xFF, (lap >> 8) & 0xFF, lap & 0xFF); str2ba(addr, &bdaddr); memset(name, 0, sizeof(name)); if (hci_read_remote_name(sock, &bdaddr, sizeof(name), name, 0) < 0) strcpy(name, "[unknown]"); printf("%s %s\n", addr, name); if (extended) extra_info(sock, dev_id, &bdaddr); } else printf("00:00:00:%02X:%02X:%02X\n", (lap >> 16) & 0xFF, (lap >> 8) & 0xFF, lap & 0xFF); btbb_print_afh_map(pn); }
int main(int argc, char *argv[]) { inquiry_info *ii = NULL; int i, opt, dev_id, dev_handle, len, flags, max_rsp, num_rsp, lap, timeout = 20; uint8_t uap, extended = 0; uint8_t scan = 0; char ubertooth_device = -1; char *bt_dev = "hci0"; char addr[19] = { 0 }; ubertooth_t* ut = NULL; btbb_piconet* pn; bdaddr_t bdaddr; while ((opt=getopt(argc,argv,"hU:t:e:xsb:")) != EOF) { switch(opt) { case 'U': ubertooth_device = atoi(optarg); break; case 'b': bt_dev = optarg; if (bt_dev == NULL) { perror(optarg); return 1; } break; case 't': timeout = atoi(optarg); break; case 'e': max_ac_errors = atoi(optarg); break; case 'x': extended = 1; break; case 's': scan = 1; break; case 'h': default: usage(); return 1; } } dev_id = hci_devid(bt_dev); if (dev_id < 0) { printf("error: Unable to find %s (%d)\n", bt_dev, dev_id); return 1; } dev_handle = hci_open_dev( dev_id ); if (dev_handle < 0) { perror("HCI device open failed"); return 1; } ut = ubertooth_start(ubertooth_device); if (ut == NULL) { usage(); return 1; } /* Set sweep mode - otherwise AFH map is useless */ cmd_set_channel(ut->devh, 9999); if (scan) { /* Equivalent to "hcitool scan" */ printf("HCI scan\n"); len = 8; max_rsp = 255; flags = IREQ_CACHE_FLUSH; ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info)); num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags); if( num_rsp < 0 ) perror("hci_inquiry"); for (i = 0; i < num_rsp; i++) { ba2str(&(ii+i)->bdaddr, addr); print_name_and_class(dev_handle, dev_id, &(ii+i)->bdaddr, addr, extended); } free(ii); } /* Now find hidden piconets with Ubertooth */ printf("\nUbertooth scan\n"); btbb_init_survey(); rx_live(ut, NULL, timeout); ubertooth_stop(ut); while((pn=btbb_next_survey_result()) != NULL) { lap = btbb_piconet_get_lap(pn); if (btbb_piconet_get_flag(pn, BTBB_UAP_VALID)) { uap = btbb_piconet_get_uap(pn); sprintf(addr, "00:00:%02X:%02X:%02X:%02X", uap, (lap >> 16) & 0xFF, (lap >> 8) & 0xFF, lap & 0xFF); str2ba(addr, &bdaddr); /* Printable version showing that the NAP is unknown */ sprintf(addr, "??:??:%02X:%02X:%02X:%02X", uap, (lap >> 16) & 0xFF, (lap >> 8) & 0xFF, lap & 0xFF); print_name_and_class(dev_handle, dev_id, &bdaddr, addr, extended); } else printf("??:??:??:%02X:%02X:%02X\n", (lap >> 16) & 0xFF, (lap >> 8) & 0xFF, lap & 0xFF); btbb_print_afh_map(pn); }
/* Sniff for LAPs. If a piconet is provided, use the given LAP to * search for UAP. */ static void cb_br_rx(void* args, usb_pkt_rx *rx, int bank) { btbb_packet *pkt = NULL; btbb_piconet *pn = (btbb_piconet *)args; char syms[BANK_LEN * NUM_BANKS]; int i; int8_t signal_level; int8_t noise_level; int8_t snr; int offset; uint32_t clkn; uint32_t lap = LAP_ANY; uint8_t uap = UAP_ANY; /* Sanity check */ if (rx->channel > (NUM_BREDR_CHANNELS-1)) goto out; /* Copy packet (for dump) */ memcpy(&usb_packets[bank], rx, sizeof(usb_pkt_rx)); unpack_symbols(rx->data, br_symbols[bank]); /* Do analysis based on oldest packet */ rx = &usb_packets[ (bank+1) % NUM_BANKS ]; uint64_t nowns = now_ns_from_clk100ns( rx ); determine_signal_and_noise( rx, &signal_level, &noise_level ); snr = signal_level - noise_level; /* WC4: use vm circbuf if target allows. This gets rid of this * wrapped copy step. */ /* Copy 2 oldest banks of symbols for analysis. Packet may * cross a bank boundary. */ for (i = 0; i < 2; i++) memcpy(syms + i * BANK_LEN, br_symbols[(i + 1 + bank) % NUM_BANKS], BANK_LEN); /* Look for packets with specified LAP, if given. Otherwise * search for any packet. Also determine if UAP is known. */ if (pn) { lap = btbb_piconet_get_flag(pn, BTBB_LAP_VALID) ? btbb_piconet_get_lap(pn) : LAP_ANY; uap = btbb_piconet_get_flag(pn, BTBB_UAP_VALID) ? btbb_piconet_get_uap(pn) : UAP_ANY; } /* Pass packet-pointer-pointer so that * packet can be created in libbtbb. */ offset = btbb_find_ac(syms, BANK_LEN, lap, max_ac_errors, &pkt); if (offset < 0) goto out; /* Copy out remaining banks of symbols for full analysis. */ for (i = 1; i < NUM_BANKS; i++) memcpy(syms + i * BANK_LEN, br_symbols[(i + 1 + bank) % NUM_BANKS], BANK_LEN); /* Once offset is known for a valid packet, copy in symbols * and other rx data. CLKN here is the 312.5us CLK27-0. The * btbb library can shift it be CLK1 if needed. */ clkn = (rx->clkn_high << 20) + (le32toh(rx->clk100ns) + offset + 1562) / 3125; btbb_packet_set_data(pkt, syms + offset, NUM_BANKS * BANK_LEN - offset, rx->channel, clkn); /* Dump to PCAP/PCAPNG if specified */ #if defined(USE_PCAP) if (h_pcap_bredr) { btbb_pcap_append_packet(h_pcap_bredr, nowns, signal_level, noise_level, lap, uap, pkt); } #endif if (h_pcapng_bredr) { btbb_pcapng_append_packet(h_pcapng_bredr, nowns, signal_level, noise_level, lap, uap, pkt); } /* When reading from file, caller will read * systime before calling this routine, so do * not overwrite. Otherwise, get current time. */ if (infile == NULL) systime = time(NULL); /* If dumpfile is specified, write out all banks to the * file. There could be duplicate data in the dump if more * than one LAP is found within the span of NUM_BANKS. */ if (dumpfile) { for(i = 0; i < NUM_BANKS; i++) { uint32_t systime_be = htobe32(systime); if (fwrite(&systime_be, sizeof(systime_be), 1, dumpfile) != 1) {;} if (fwrite(&usb_packets[(i + 1 + bank) % NUM_BANKS], sizeof(usb_pkt_rx), 1, dumpfile) != 1) {;} } } printf("systime=%u ch=%2d LAP=%06x err=%u clk100ns=%u clk1=%u s=%d n=%d snr=%d\n", (int)systime, btbb_packet_get_channel(pkt), btbb_packet_get_lap(pkt), btbb_packet_get_ac_errors(pkt), rx->clk100ns, btbb_packet_get_clkn(pkt), signal_level, noise_level, snr); i = btbb_process_packet(pkt, pn); if(i < 0) { follow_pn = pn; stop_ubertooth = 1; } out: if (pkt) btbb_packet_unref(pkt); }