int main(int argc, char *argv[]) { int opt; int do_follow, do_file, do_promisc; int do_get_aa, do_set_aa; int do_crc; int do_adv_index; int do_slave_mode; int do_target; char ubertooth_device = -1; btle_options cb_opts = { .allowed_access_address_errors = 32 }; int r; u32 access_address; uint8_t mac_address[6] = { 0, }; do_follow = do_file = 0, do_promisc = 0; do_get_aa = do_set_aa = 0; do_crc = -1; // 0 and 1 mean set, 2 means get do_adv_index = 37; do_slave_mode = do_target = 0; while ((opt=getopt(argc,argv,"a::r:d:hfpi:U:v::A:s:t:x:c:q:")) != EOF) { switch(opt) { case 'a': if (optarg == NULL) { do_get_aa = 1; } else { do_set_aa = 1; sscanf(optarg, "%08x", &access_address); } break; case 'f': do_follow = 1; break; case 'p': do_promisc = 1; break; case 'i': do_file = 1; infile = fopen(optarg, "r"); if (infile == NULL) { printf("Could not open file %s\n", optarg); usage(); return 1; } break; case 'U': ubertooth_device = atoi(optarg); break; case 'r': if (!h_pcapng_le) { if (lell_pcapng_create_file(optarg, "Ubertooth", &h_pcapng_le)) { err(1, "lell_pcapng_create_file: "); } } else { printf("Ignoring extra capture file: %s\n", optarg); } break; #ifdef ENABLE_PCAP case 'q': if (!h_pcap_le) { if (lell_pcap_create_file(optarg, &h_pcap_le)) { err(1, "lell_pcap_create_file: "); } } else { printf("Ignoring extra capture file: %s\n", optarg); } break; case 'c': if (!h_pcap_le) { if (lell_pcap_ppi_create_file(optarg, 0, &h_pcap_le)) { err(1, "lell_pcap_ppi_create_file: "); } } else { printf("Ignoring extra capture file: %s\n", optarg); } break; #endif case 'd': dumpfile = fopen(optarg, "w"); if (dumpfile == NULL) { perror(optarg); return 1; } break; case 'v': if (optarg) do_crc = atoi(optarg) ? 1 : 0; else do_crc = 2; // get break; case 'A': do_adv_index = atoi(optarg); if (do_adv_index < 37 || do_adv_index > 39) { printf("Error: advertising index must be 37, 38, or 39\n"); usage(); return 1; } break; case 's': do_slave_mode = 1; r = convert_mac_address(optarg, mac_address); if (!r) { usage(); return 1; } break; case 't': do_target = 1; r = convert_mac_address(optarg, mac_address); if (!r) { usage(); return 1; } break; case 'x': cb_opts.allowed_access_address_errors = (unsigned) atoi(optarg); if (cb_opts.allowed_access_address_errors > 32) { printf("Error: can tolerate 0-32 access address bit errors\n"); usage(); return 1; } break; case 'h': default: usage(); return 1; } } if (do_file) { rx_btle_file(infile); fclose(infile); return 0; // do file is the only command that doesn't open ubertooth } devh = ubertooth_start(ubertooth_device); if (devh == NULL) { usage(); return 1; } /* Clean up on exit. */ signal(SIGINT, cleanup); signal(SIGQUIT, cleanup); signal(SIGTERM, cleanup); if (do_follow || do_promisc) { usb_pkt_rx pkt; cmd_set_modulation(devh, MOD_BT_LOW_ENERGY); if (do_follow) { u16 channel; if (do_adv_index == 37) channel = 2402; else if (do_adv_index == 38) channel = 2426; else channel = 2480; cmd_set_channel(devh, channel); cmd_btle_sniffing(devh, 2); } else { cmd_btle_promisc(devh); } while (1) { int r = cmd_poll(devh, &pkt); if (r < 0) { printf("USB error\n"); break; } if (r == sizeof(usb_pkt_rx)) cb_btle(&cb_opts, &pkt, 0); usleep(500); } ubertooth_stop(devh); } if (do_get_aa) { access_address = cmd_get_access_address(devh); printf("Access address: %08x\n", access_address); return 0; } if (do_set_aa) { cmd_set_access_address(devh, access_address); printf("access address set to: %08x\n", access_address); } if (do_crc >= 0) { int r; if (do_crc == 2) { r = cmd_get_crc_verify(devh); } else { cmd_set_crc_verify(devh, do_crc); r = do_crc; } printf("CRC: %sverify\n", r ? "" : "DO NOT "); } if (do_slave_mode) { u16 channel; if (do_adv_index == 37) channel = 2402; else if (do_adv_index == 38) channel = 2426; else channel = 2480; cmd_set_channel(devh, channel); cmd_btle_slave(devh, mac_address); } if (do_target) { r = cmd_btle_set_target(devh, mac_address); if (r == 0) { int i; printf("target set to: "); for (i = 0; i < 5; ++i) printf("%02x:", mac_address[i]); printf("%02x\n", mac_address[5]); } } return 0; }
int main(int argc, char *argv[]) { int opt; int do_follow, do_promisc; int do_get_aa, do_set_aa; int do_crc; int do_adv_index; int do_slave_mode; int do_target; enum jam_modes jam_mode = JAM_NONE; char ubertooth_device = -1; ubertooth_t* ut = ubertooth_init(); btle_options cb_opts = { .allowed_access_address_errors = 32 }; int r; u32 access_address; uint8_t mac_address[6] = { 0, }; do_follow = do_promisc = 0; do_get_aa = do_set_aa = 0; do_crc = -1; // 0 and 1 mean set, 2 means get do_adv_index = 37; do_slave_mode = do_target = 0; while ((opt=getopt(argc,argv,"a::r:hfpU:v::A:s:t:x:c:q:jJiI")) != EOF) { switch(opt) { case 'a': if (optarg == NULL) { do_get_aa = 1; } else { do_set_aa = 1; sscanf(optarg, "%08x", &access_address); } break; case 'f': do_follow = 1; break; case 'p': do_promisc = 1; break; case 'U': ubertooth_device = atoi(optarg); break; case 'r': if (!ut->h_pcapng_le) { if (lell_pcapng_create_file(optarg, "Ubertooth", &ut->h_pcapng_le)) { err(1, "lell_pcapng_create_file: "); } } else { printf("Ignoring extra capture file: %s\n", optarg); } break; #ifdef ENABLE_PCAP case 'q': if (!ut->h_pcap_le) { if (lell_pcap_create_file(optarg, &ut->h_pcap_le)) { err(1, "lell_pcap_create_file: "); } } else { printf("Ignoring extra capture file: %s\n", optarg); } break; case 'c': if (!ut->h_pcap_le) { if (lell_pcap_ppi_create_file(optarg, 0, &ut->h_pcap_le)) { err(1, "lell_pcap_ppi_create_file: "); } } else { printf("Ignoring extra capture file: %s\n", optarg); } break; #endif case 'v': if (optarg) do_crc = atoi(optarg) ? 1 : 0; else do_crc = 2; // get break; case 'A': do_adv_index = atoi(optarg); if (do_adv_index < 37 || do_adv_index > 39) { printf("Error: advertising index must be 37, 38, or 39\n"); usage(); return 1; } break; case 's': do_slave_mode = 1; r = convert_mac_address(optarg, mac_address); if (!r) { usage(); return 1; } break; case 't': do_target = 1; r = convert_mac_address(optarg, mac_address); if (!r) { usage(); return 1; } break; case 'x': cb_opts.allowed_access_address_errors = (unsigned) atoi(optarg); if (cb_opts.allowed_access_address_errors > 32) { printf("Error: can tolerate 0-32 access address bit errors\n"); usage(); return 1; } break; case 'i': case 'j': jam_mode = JAM_ONCE; break; case 'I': case 'J': jam_mode = JAM_CONTINUOUS; break; case 'h': default: usage(); return 1; } } r = ubertooth_connect(ut, ubertooth_device); if (r < 0) { usage(); return 1; } /* Clean up on exit. */ register_cleanup_handler(ut); if (do_follow && do_promisc) { printf("Error: must choose either -f or -p, one or the other pal\n"); return 1; } if (do_follow || do_promisc) { usb_pkt_rx rx; r = cmd_set_jam_mode(ut->devh, jam_mode); if (jam_mode != JAM_NONE && r != 0) { printf("Jamming not supported\n"); return 1; } cmd_set_modulation(ut->devh, MOD_BT_LOW_ENERGY); if (do_follow) { u16 channel; if (do_adv_index == 37) channel = 2402; else if (do_adv_index == 38) channel = 2426; else channel = 2480; cmd_set_channel(ut->devh, channel); cmd_btle_sniffing(ut->devh, 2); } else { cmd_btle_promisc(ut->devh); } while (1) { int r = cmd_poll(ut->devh, &rx); if (r < 0) { printf("USB error\n"); break; } if (r == sizeof(usb_pkt_rx)) { ringbuffer_add(ut->packets, &rx); cb_btle(ut, &cb_opts); } usleep(500); } ubertooth_stop(ut); } if (do_get_aa) { access_address = cmd_get_access_address(ut->devh); printf("Access address: %08x\n", access_address); return 0; } if (do_set_aa) { cmd_set_access_address(ut->devh, access_address); printf("access address set to: %08x\n", access_address); } if (do_crc >= 0) { int r; if (do_crc == 2) { r = cmd_get_crc_verify(ut->devh); } else { cmd_set_crc_verify(ut->devh, do_crc); r = do_crc; } printf("CRC: %sverify\n", r ? "" : "DO NOT "); } if (do_slave_mode) { u16 channel; if (do_adv_index == 37) channel = 2402; else if (do_adv_index == 38) channel = 2426; else channel = 2480; cmd_set_channel(ut->devh, channel); cmd_btle_slave(ut->devh, mac_address); } if (do_target) { r = cmd_btle_set_target(ut->devh, mac_address); if (r == 0) { int i; printf("target set to: "); for (i = 0; i < 5; ++i) printf("%02x:", mac_address[i]); printf("%02x\n", mac_address[5]); } } if (!(do_follow || do_promisc || do_get_aa || do_set_aa || do_crc >= 0 || do_slave_mode || do_target)) usage(); return 0; }