// If controler == NULL, we take the first present available BT adaptator. hci_socket_t open_hci_socket(bdaddr_t *controller) { hci_socket_t result; memset(&result, 0, sizeof(result)); if (controller) { char add[18]; ba2str(controller, add); result.dev_id = hci_devid(add); } else { result.dev_id = hci_get_route(NULL); } if (result.dev_id < 0) { perror("open_hci_socket"); result.sock = -1; return result; } result.sock = hci_open_dev(result.dev_id); if (result.sock < 0) { perror("open_hci_socket"); result.sock = -1; return result; } return result; }
static inline int get_bdaddr(int dev, bdaddr_t *sba, uint16_t handle, bdaddr_t *dba) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; char addr[18]; int i; cl = malloc(10 * sizeof(*ci) + sizeof(*cl)); if (!cl) return -ENOMEM; ba2str(sba, addr); cl->dev_id = hci_devid(addr); cl->conn_num = 10; ci = cl->conn_info; if (ioctl(dev, HCIGETCONNLIST, (void *) cl) < 0) { free(cl); return -EIO; } for (i = 0; i < cl->conn_num; i++, ci++) if (ci->handle == handle) { bacpy(dba, &ci->bdaddr); free(cl); return 0; } free(cl); return -ENOENT; }
int main(int argc, char *argv[]) { int dev_id; int ret; if (argc == 1) { dev_id = hci_get_route(NULL); } else if (argc == 2) { dev_id = hci_devid(argv[1]); } else { fprintf(stderr, "%s [<bluetooth-adapter>]\n", argv[0]); return 1; } if (dev_id < 0) { fprintf(stderr, "ERROR: Invalid device.\n"); return 1; } LIST_INIT(&g_ble_connections); device_desc = hci_open_dev(dev_id); if (device_desc < 0) { fprintf(stderr, "ERROR: Could not open device.\n"); return 1; } ret = ble_scan_enable(device_desc); if (ret != 0) { fprintf(stderr, "ERROR: Scanning fail.\n"); return 1; } pthread_mutex_lock(&g_mutex); ret = ble_scan(device_desc, ble_discovered_device, BLE_SCAN_TIMEOUT); if (ret != 0) { fprintf(stderr, "ERROR: Advertisement fail.\n"); return 1; } ble_scan_disable(device_desc); puts("Scan completed"); pthread_mutex_unlock(&g_mutex); // Wait for the thread to complete while (g_ble_connections.lh_first != NULL) { struct connection_t* connection = g_ble_connections.lh_first; pthread_join(connection->thread, NULL); LIST_REMOVE(g_ble_connections.lh_first, entries); free(connection->addr); free(connection); } return 0; }
int main(int argc, char *argv[]) { char *address = "14:1a:a3:9b:41:8e"; int dev_id = hci_devid(address); struct hci_dev_info *di = (struct hci_dev_info *)malloc(sizeof(struct hci_dev_info)); int rtn = hci_devinfo(dev_id, di); printf("%s\n", di->name); return 0; }
int get_device_id(char* bdaddr) { int id = 0; if(bdaddr) { id = hci_devid(bdaddr); } else { id = hci_get_route(NULL); } return id; }
struct HCIInfo *bt_host_hci(const char *id) { struct bt_host_hci_s *s; int fd = -1; # ifdef CONFIG_BLUEZ int dev_id = hci_devid(id); struct hci_filter flt; if (dev_id < 0) { fprintf(stderr, "qemu: `%s' not available\n", id); return 0; } fd = hci_open_dev(dev_id); /* XXX: can we ensure nobody else has the device opened? */ # endif if (fd < 0) { fprintf(stderr, "qemu: Can't open `%s': %s (%i)\n", id, strerror(errno), errno); return NULL; } # ifdef CONFIG_BLUEZ hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { fprintf(stderr, "qemu: Can't set HCI filter on socket (%i)\n", errno); return 0; } # endif s = g_malloc0(sizeof(struct bt_host_hci_s)); s->fd = fd; s->hci.cmd_send = bt_host_cmd; s->hci.sco_send = bt_host_sco; s->hci.acl_send = bt_host_acl; s->hci.bdaddr_set = bt_host_bdaddr_set; qemu_set_fd_handler(s->fd, bt_host_read, NULL, s); return &s->hci; }
int main(int argc, char **argv) { int opt, i, dev_id = -1; bdaddr_t ba; while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { case 'i': dev_id = hci_devid(optarg); if (dev_id < 0) { perror("Invalid device"); exit(1); } break; case 'h': default: usage(); exit(0); } } argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); exit(0); } if (dev_id != -1 && hci_devba(dev_id, &ba) < 0) { perror("Device is not available"); exit(1); } for (i=0; command[i].cmd; i++) { if (strncmp(command[i].cmd, argv[0], 3)) continue; command[i].func(dev_id, argc, argv); break; } return 0; }
int csr_open_hci(char *device) { struct hci_dev_info di; struct hci_version ver; int dev = 0; if (device) { dev = hci_devid(device); if (dev < 0) { fprintf(stderr, "Device not available\n"); return -1; } } dd = hci_open_dev(dev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", dev, strerror(errno), errno); return -1; } if (hci_devinfo(dev, &di) < 0) { fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); return -1; } if (hci_read_local_version(dd, &ver, 1000) < 0) { fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); return -1; } if (ver.manufacturer != 10) { fprintf(stderr, "Unsupported manufacturer\n"); hci_close_dev(dd); return -1; } return 0; }
CBlueZStack::CBlueZStack(): CGenericBluetoothStack(), m_fd(-1) { if (g_devId < 0) { // retrieve local bluetooth address from environment variable const char *addr = getenv("JSR82BTADDR"); if (addr != NULL) { g_devId = hci_devid(addr); } else { g_devId = hci_get_route(NULL); } if (g_devId < 0) { return; } hci_dev_info di; hci_devinfo(g_devId, &di); } m_fd = hci_open_dev(g_devId); if (m_fd < 0) { return; } fcntl(m_fd, F_SETFL, O_NONBLOCK); hci_filter flt; hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_CMD_COMPLETE, &flt); hci_filter_set_event(EVT_CMD_STATUS, &flt); hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); hci_filter_set_event(EVT_AUTH_COMPLETE, &flt); hci_filter_set_event(EVT_ENCRYPT_CHANGE, &flt); if (setsockopt(m_fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { return; } m_poll.fd = m_fd; m_poll.events = POLLIN | POLLHUP | POLLERR; m_poll.revents = 0; m_bInitialized = true; }
int main(void) { switch(fork()) { case -1: die("fork\n"); break; case 0: dev_id = hci_devid(DEV_ID); if (dev_id < 0) { die("Invalid device\n"); } else { initsignals(); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); Display *dpy = NULL; int rssi, screen; Bool help = True; check_version(dev_id); add_to_white_list(dev_id); handle = connect_to_device(dev_id); /* encryption(dev_id, handle); */ while (running) { if (help) { if (!(dpy = XOpenDisplay(0))) die("ble: cannot open display"); /* Get the number of screens in display "dpy" and blank them all. */ nscreens = ScreenCount(dpy); locks = malloc(sizeof(Lock *) * nscreens); if (locks == NULL) die("ble: malloc: %s", strerror(errno)); } if (help) { rssi = read_rssi(dev_id, handle); if ((calculate_distance(rssi) >= 2.0) && (rssi <= -71 && rssi >= -75)) { if (locks != NULL && help) { for (screen = 0; screen < nscreens; screen++) locks[screen] = lockscreen(dpy, screen); XSync(dpy, False); } help = False; } } sleep(1); if (!help) { rssi = read_rssi(dev_id, handle); if ((calculate_distance(rssi) <= 2.0) && (rssi <= -30 && rssi >= -70)) { for (screen = 0; screen < nscreens; screen++) unlockscreen(dpy, locks[screen]); if (locks != NULL || dpy != NULL) { free(locks); XCloseDisplay(dpy); help = True; } } } } disconnect_from_device(dev_id, handle); } default: break; } return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { int opt; bdaddr_t src_addr; int dev_id = -1; int fd; int sec = BT_SECURITY_LOW; uint8_t src_type = BDADDR_LE_PUBLIC; uint16_t mtu = 0; sigset_t mask; bool hr_visible = false; struct server *server; while ((opt = getopt_long(argc, argv, "+hvrs:t:m:i:", main_options, NULL)) != -1) { switch (opt) { case 'h': usage(); return EXIT_SUCCESS; case 'v': verbose = true; break; case 'r': hr_visible = true; break; case 's': if (strcmp(optarg, "low") == 0) sec = BT_SECURITY_LOW; else if (strcmp(optarg, "medium") == 0) sec = BT_SECURITY_MEDIUM; else if (strcmp(optarg, "high") == 0) sec = BT_SECURITY_HIGH; else { fprintf(stderr, "Invalid security level\n"); return EXIT_FAILURE; } break; case 't': if (strcmp(optarg, "random") == 0) src_type = BDADDR_LE_RANDOM; else if (strcmp(optarg, "public") == 0) src_type = BDADDR_LE_PUBLIC; else { fprintf(stderr, "Allowed types: random, public\n"); return EXIT_FAILURE; } break; case 'm': { int arg; arg = atoi(optarg); if (arg <= 0) { fprintf(stderr, "Invalid MTU: %d\n", arg); return EXIT_FAILURE; } if (arg > UINT16_MAX) { fprintf(stderr, "MTU too large: %d\n", arg); return EXIT_FAILURE; } mtu = (uint16_t) arg; break; } case 'i': dev_id = hci_devid(optarg); if (dev_id < 0) { perror("Invalid adapter"); return EXIT_FAILURE; } break; default: fprintf(stderr, "Invalid option: %c\n", opt); return EXIT_FAILURE; } } argc -= optind; argv -= optind; optind = 0; if (argc) { usage(); return EXIT_SUCCESS; } if (dev_id == -1) bacpy(&src_addr, BDADDR_ANY); else if (hci_devba(dev_id, &src_addr) < 0) { perror("Adapter not available"); return EXIT_FAILURE; } fd = l2cap_le_att_listen_and_accept(&src_addr, sec, src_type); if (fd < 0) { fprintf(stderr, "Failed to accept L2CAP ATT connection\n"); return EXIT_FAILURE; } mainloop_init(); server = server_create(fd, mtu, hr_visible); if (!server) { close(fd); return EXIT_FAILURE; } if (mainloop_add_fd(fileno(stdin), EPOLLIN | EPOLLRDHUP | EPOLLHUP | EPOLLERR, prompt_read_cb, server, NULL) < 0) { fprintf(stderr, "Failed to initialize console\n"); server_destroy(server); return EXIT_FAILURE; } printf("Running GATT server\n"); sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); mainloop_set_signal(&mask, signal_cb, NULL, NULL); print_prompt(); mainloop_run(); printf("\n\nShutting down...\n"); server_destroy(server); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { struct sigaction sa; GIOChannel *dev_io; char *device = NULL, *snoop = NULL; bdaddr_t bdaddr; int fd, dd, opt, detach = 1, dev = -1; bacpy(&bdaddr, BDADDR_ANY); while ((opt=getopt_long(argc, argv, "d:b:s:nh", main_options, NULL)) != EOF) { switch(opt) { case 'd': device = strdup(optarg); break; case 'b': str2ba(optarg, &bdaddr); break; case 's': snoop = strdup(optarg); break; case 'n': detach = 0; break; case 'h': default: usage(); exit(0); } } argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); exit(1); } if (strlen(argv[0]) > 3 && !strncasecmp(argv[0], "hci", 3)) { dev = hci_devid(argv[0]); if (dev < 0) { perror("Invalid device"); exit(1); } } else { if (getbdaddrbyname(argv[0], &vdev.bdaddr) < 0) exit(1); } if (detach) { if (daemon(0, 0)) { perror("Can't start daemon"); exit(1); } } /* Start logging to syslog and stderr */ openlog("hciemu", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); syslog(LOG_INFO, "HCI emulation daemon ver %s started", VERSION); memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); io_init(); if (!device && dev >= 0) device = strdup(GHCI_DEV); /* Open and create virtual HCI device */ if (device) { fd = open(device, O_RDWR); if (fd < 0) { syslog(LOG_ERR, "Can't open device %s: %s (%d)", device, strerror(errno), errno); free(device); exit(1); } free(device); } else { fd = open(VHCI_DEV, O_RDWR); if (fd < 0) { fd = open(VHCI_UDEV, O_RDWR); if (fd < 0) { syslog(LOG_ERR, "Can't open device %s: %s (%d)", VHCI_DEV, strerror(errno), errno); exit(1); } } } /* Create snoop file */ if (snoop) { dd = create_snoop(snoop); if (dd < 0) syslog(LOG_ERR, "Can't create snoop file %s: %s (%d)", snoop, strerror(errno), errno); free(snoop); } else dd = -1; /* Create event loop */ event_loop = g_main_loop_new(NULL, FALSE); if (dev >= 0) return run_proxy(fd, dev, &bdaddr); /* Device settings */ vdev.features[0] = 0xff; vdev.features[1] = 0xff; vdev.features[2] = 0x8f; vdev.features[3] = 0xfe; vdev.features[4] = 0x9b; vdev.features[5] = 0xf9; vdev.features[6] = 0x01; vdev.features[7] = 0x80; memset(vdev.name, 0, sizeof(vdev.name)); strncpy((char *) vdev.name, "BlueZ (Virtual HCI)", sizeof(vdev.name) - 1); vdev.dev_class[0] = 0x00; vdev.dev_class[1] = 0x00; vdev.dev_class[2] = 0x00; vdev.inq_mode = 0x00; vdev.eir_fec = 0x00; memset(vdev.eir_data, 0, sizeof(vdev.eir_data)); vdev.fd = fd; vdev.dd = dd; dev_io = g_io_channel_unix_new(fd); g_io_add_watch(dev_io, G_IO_IN, io_hci_data, NULL); setpriority(PRIO_PROCESS, 0, -19); /* Start event processor */ g_main_loop_run(event_loop); close(fd); if (dd >= 0) close(dd); syslog(LOG_INFO, "Exit"); return 0; }
int main(int argc, char *argv[]) { uint8_t events[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00 }; struct hci_dev_info di; struct hci_version ver; int dd, opt, dev = 0; while ((opt=getopt_long(argc, argv, "+i:", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); if (dev < 0) { perror("Invalid device"); exit(1); } break; } } dd = hci_open_dev(dev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", dev, strerror(errno), errno); exit(1); } if (hci_devinfo(dev, &di) < 0) { fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } if (hci_read_local_version(dd, &ver, 1000) < 0) { fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } hci_close_dev(dd); if (ver.hci_ver > 1) { if (di.features[5] & LMP_SNIFF_SUBR) events[5] |= 0x20; if (di.features[5] & LMP_PAUSE_ENC) events[5] |= 0x80; if (di.features[6] & LMP_EXT_INQ) events[5] |= 0x40; if (di.features[6] & LMP_NFLUSH_PKTS) events[7] |= 0x01; if (di.features[7] & LMP_LSTO) events[6] |= 0x80; if (di.features[6] & LMP_SIMPLE_PAIR) { events[6] |= 0x01; /* IO Capability Request */ events[6] |= 0x02; /* IO Capability Response */ events[6] |= 0x04; /* User Confirmation Request */ events[6] |= 0x08; /* User Passkey Request */ events[6] |= 0x10; /* Remote OOB Data Request */ events[6] |= 0x20; /* Simple Pairing Complete */ events[7] |= 0x04; /* User Passkey Notification */ events[7] |= 0x08; /* Keypress Notification */ events[7] |= 0x10; /* Remote Host Supported * Features Notification */ } if (di.features[4] & LMP_LE) events[7] |= 0x20; if (di.features[6] & LMP_LE_BREDR) events[7] |= 0x20; } printf("Setting event mask:\n"); printf("\thcitool cmd 0x%02x 0x%04x " "0x%02x 0x%02x 0x%02x 0x%02x " "0x%02x 0x%02x 0x%02x 0x%02x\n", OGF_HOST_CTL, OCF_SET_EVENT_MASK, events[0], events[1], events[2], events[3], events[4], events[5], events[6], events[7]); return 0; }
int main(int argc, char *argv[]) { int opt, sock, dev_id, lap = 0, uap = 0, delay = 5; int have_lap = 0; int have_uap = 0; int afh_enabled = 0; uint8_t mode, afh_map[10]; char *end, ubertooth_device = -1; char *bt_dev = "hci0"; char addr[19] = { 0 }; uint32_t clock; uint16_t accuracy, handle, offset; bdaddr_t bdaddr; btbb_piconet *pn; struct hci_dev_info di; int cc = 0; pn = btbb_piconet_new(); while ((opt=getopt(argc,argv,"hl:u:U:e:d:ab:w:r:q:")) != EOF) { switch(opt) { case 'l': lap = strtol(optarg, &end, 16); if (end != optarg) { ++have_lap; } break; case 'u': uap = strtol(optarg, &end, 16); if (end != optarg) { ++have_uap; } break; case 'U': ubertooth_device = atoi(optarg); break; case 'r': if (!h_pcapng_bredr) { if (btbb_pcapng_create_file( optarg, "Ubertooth", &h_pcapng_bredr )) { err(1, "create_bredr_capture_file: "); } } else { printf("Ignoring extra capture file: %s\n", optarg); } break; #ifdef ENABLE_PCAP case 'q': if (!h_pcap_bredr) { if (btbb_pcap_create_file(optarg, &h_pcap_bredr)) { err(1, "btbb_pcap_create_file: "); } } else { printf("Ignoring extra capture file: %s\n", optarg); } break; #endif case 'e': max_ac_errors = atoi(optarg); break; case 'd': dumpfile = fopen(optarg, "w"); if (dumpfile == NULL) { perror(optarg); return 1; } break; case 'a': afh_enabled = 1; break; case 'b': bt_dev = optarg; if (bt_dev == NULL) { perror(optarg); return 1; } break; case 'w': //wait delay = atoi(optarg); break; case 'h': default: usage(); return 1; } } dev_id = hci_devid(bt_dev); sock = hci_open_dev(dev_id); hci_read_clock(sock, 0, 0, &clock, &accuracy, 0); if ((have_lap != 1) || (have_uap != 1)) { printf("No address given, reading address from device\n"); hci_read_bd_addr(sock, &bdaddr, 0); lap = bdaddr.b[0] | bdaddr.b[1] << 8 | bdaddr.b[2] << 16; btbb_init_piconet(pn, lap); uap = bdaddr.b[3]; btbb_piconet_set_uap(pn, uap); printf("LAP=%06x UAP=%02x\n", lap, uap); } else if (have_lap && have_uap) { btbb_init_piconet(pn, lap); btbb_piconet_set_uap(pn, uap); printf("Address given, assuming address is remote\n"); sprintf(addr, "00:00:%02X:%02X:%02X:%02X", uap, (lap >> 16) & 0xFF, (lap >> 8) & 0xFF, lap & 0xFF ); str2ba(addr, &bdaddr); printf("Address: %s\n", addr); if (hci_devinfo(dev_id, &di) < 0) { perror("Can't get device info"); return 1; } if (hci_create_connection(sock, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); return 1; } sleep(1); cc = 1; if (hci_read_clock_offset(sock, handle, &offset, 1000) < 0) { perror("Reading clock offset failed"); } clock += offset; } else {
int main(int argc, char **argv) { char *dst = NULL, *src = NULL; struct sigaction sa; int mode = NONE; int opt; while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) { switch(opt) { case 'l': mode = SHOW; detach = 0; break; case 's': mode = LISTEN; break; case 'c': mode = CONNECT; dst = strdup(optarg); break; case 'Q': mode = CONNECT; dst = NULL; if (optarg) search_duration = atoi(optarg); break; case 'k': mode = KILL; detach = 0; dst = strdup(optarg); break; case 'K': mode = KILL; detach = 0; dst = NULL; break; case 'P': channel = atoi(optarg); break; case 'i': src = strdup(optarg); break; case 'D': use_sdp = 0; break; case 'A': auth = 1; break; case 'E': encrypt = 1; break; case 'S': secure = 1; break; case 'M': master = 1; break; case 'n': detach = 0; break; case 'p': if (optarg) persist = atoi(optarg); else persist = 5; break; case 'C': if (optarg) use_cache = atoi(optarg); else use_cache = 2; break; case 'd': pppd = strdup(optarg); break; case 'X': if (optarg) msdun = atoi(optarg); else msdun = 10; break; case 'a': msdun = 10; type = ACTIVESYNC; break; case 'm': mode = LISTEN; dst = strdup(optarg); type = MROUTER; break; case 'u': mode = LISTEN; type = DIALUP; break; case 'h': default: printf(main_help); exit(0); } } argc -= optind; argv += optind; /* The rest is pppd options */ if (argc > 0) { for (opt = 3; argc && opt < DUN_MAX_PPP_OPTS; argc--, opt++) pppd_opts[opt] = *argv++; pppd_opts[opt] = NULL; } io_init(); if (dun_init()) return -1; /* Check non daemon modes first */ switch (mode) { case SHOW: do_show(); return 0; case KILL: do_kill(dst); return 0; case NONE: printf(main_help); return 0; } /* Initialize signals */ memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); if (detach) { int fd; if (vfork()) exit(0); /* Direct stdin,stdout,stderr to '/dev/null' */ fd = open("/dev/null", O_RDWR); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); setsid(); chdir("/"); } openlog("dund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); syslog(LOG_INFO, "Bluetooth DUN daemon version %s", VERSION); if (src) { src_dev = hci_devid(src); if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) { syslog(LOG_ERR, "Invalid source. %s(%d)", strerror(errno), errno); return -1; } } if (dst) { strncpy(cache.dst, dst, sizeof(cache.dst) - 1); str2ba(dst, &cache.bdaddr); /* Disable cache invalidation */ use_cache = cache.valid = ~0; } switch (mode) { case CONNECT: do_connect(); break; case LISTEN: do_listen(); break; } return 0; }
int main(int argc, char *argv[]) { // Handle signals signal(SIGINT,shut_down); signal(SIGHUP,shut_down); signal(SIGTERM,shut_down); signal(SIGQUIT,shut_down); // HCI device number, MAC struct int device = 0; bdaddr_t bdaddr; bacpy(&bdaddr, BDADDR_ANY); // Time to scan. Scan time is roughly 1.28 seconds * scan_window // Originally this was always 8, now we adjust based on device: #ifdef OPENWRT int scan_window = 8; #elif PWNPLUG int scan_window = 5; #else int scan_window = 3; #endif // Maximum number of devices per scan int max_results = 255; int num_results; // Device cache and index int cache_index = 0; // HCI cache setting int flags = IREQ_CACHE_FLUSH; // Strings to hold MAC and name char addr[19] = {0}; char addr_buff[19] = {0}; // String for time char cur_time[20]; // Process ID read from PID file int ext_pid; // Pointers to filenames char *infofilename = LIVE_INF; // Change default filename based on date char OUT_FILE[1000] = OUT_PATH; strncat(OUT_FILE, file_timestamp(),sizeof(OUT_FILE)-strlen(OUT_FILE)-1); char *outfilename = OUT_FILE; // Mode to open output file in char *filemode = "a+"; // Output buffer char outbuffer[500]; // Buffer for data from the second loop char exitbuffer[500]; // Misc Variables int i, ri, opt; // Record numbner of BlueZ errors int error_count = 0; // Current epoch time long long int epoch; // Kernel version info struct utsname sysinfo; uname(&sysinfo); while ((opt=getopt_long(argc,argv,"+o:i:r:a:w:vxctghldbfenksmq", main_options, NULL)) != EOF) { switch (opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) hci_devba(atoi(optarg + 3), &bdaddr); else str2ba(optarg, &bdaddr); break; case 'o': outfilename = strdup(optarg); break; case 'r': config.retry_count = atoi(optarg); break; case 'a': config.amnesia = atoi(optarg); break; case 'w': config.scan_window = round((atoi(optarg) / 1.28)); break; case 'c': config.showclass = 1; break; case 'e': config.encode = 1; break; case 'f': config.friendlyclass = 1; break; case 'v': config.verbose = 1; break; case 'g': config.status = 1; break; case 't': config.showtime = 1; break; case 's': config.syslogonly = 1; break; case 'x': config.obfuscate = 1; break; case 'q': config.quiet = 1; break; case 'l': if(!LIVEMODE) { printf("Live mode has been disabled in this build. See documentation.\n"); exit(0); } else config.bluelive = 1; break; case 'b': config.bluepropro = 1; break; case 'd': config.daemon = 1; break; case 'n': config.getname = 1; break; case 'm': if(!OUILOOKUP) { printf("Manufacturer lookups have been disabled in this build. See documentation.\n"); exit(0); } else config.getmanufacturer = 1; break; case 'h': help(); exit(0); case 'k': // Read PID from file into variable ext_pid = read_pid(); if (ext_pid != 0) { printf("Killing Bluelog process with PID %i...",ext_pid); if(kill(ext_pid,15) != 0) { printf("ERROR!\n"); printf("Unable to kill Bluelog process. Check permissions.\n"); exit(1); } else printf("OK.\n"); // Delete PID file unlink(PID_FILE); } else printf("No running Bluelog process found.\n"); exit(0); default: printf("Unknown option. Use -h for help, or see README.\n"); exit(1); } } // See if there is already a process running if (read_pid() != 0) { printf("Another instance of Bluelog is already running!\n"); printf("Use the -k option to kill a running Bluelog process.\n"); exit(1); } // Load config from file if no options given on command line if(cfg_exists() && argc == 1) { if (cfg_read() != 0) { printf("Error opening config file!\n"); exit(1); } // Put interface into BT struct hci_devba(config.hci_device, &bdaddr); } // Perform sanity checks on varibles cfg_check(); // Setup libmackerel mac_init(); // Boilerplate if (!config.quiet) { printf("%s (v%s%s) by MS3FGX\n", APPNAME, VERSION, VER_MOD); #if defined OPENWRT || PWNPLUG printf("----"); #endif printf("---------------------------\n"); } // Show notification we loaded config from file if(cfg_exists() && argc == 1 && !config.quiet) printf("Config loaded from: %s\n", CFG_FILE); // Init Hardware ba2str(&bdaddr, config.addr); if (!strcmp(config.addr, "00:00:00:00:00:00")) { if (!config.quiet) printf("Autodetecting device..."); device = hci_get_route(NULL); // Put autodetected device MAC into addr hci_devba(device, &bdaddr); ba2str(&bdaddr, config.addr); } else { if (!config.quiet) printf("Initializing device..."); device = hci_devid(config.addr); } // Open device and catch errors config.bt_socket = hci_open_dev(device); if (device < 0 || config.bt_socket < 0) { // Failed to open device, that can't be good printf("\n"); printf("Error initializing Bluetooth device!\n"); exit(1); } // If we get here the device should be online. if (!config.quiet) printf("OK\n"); // Status message for BPP if (!config.quiet) if (config.bluepropro) printf("Output formatted for BlueProPro.\n" "More Info: www.hackfromacave.com\n"); // Open socket if (config.udponly) open_udp_socket(); // Open output file, unless in networking mode if (!config.syslogonly && !config.udponly) { if (config.bluelive) { // Change location of output file outfilename = LIVE_OUT; filemode = "w"; if (!config.quiet) printf("Starting Bluelog Live...\n"); } if (!config.quiet) printf("Opening output file: %s...", outfilename); if ((outfile = fopen(outfilename, filemode)) == NULL) { printf("\n"); printf("Error opening output file!\n"); exit(1); } if (!config.quiet) printf("OK\n"); } else if (!config.quiet) printf("Network mode enabled, not creating log file.\n"); // Open status file if (config.bluelive) { if (!config.quiet) printf("Opening info file: %s...", infofilename); if ((infofile = fopen(infofilename,"w")) == NULL) { printf("\n"); printf("Error opening info file!\n"); exit(1); } if (!config.quiet) printf("OK\n"); } // Write PID file if (!config.daemon) write_pid(getpid()); // Get and print time to console and file strcpy(cur_time, get_localtime()); if (!config.daemon) printf("Scan started at [%s] on %s\n", cur_time, config.addr); if (config.showtime && (outfile != NULL)) { fprintf(outfile,"[%s] Scan started on %s\n", cur_time, config.addr); // Make sure this gets written out fflush(outfile); } // Write info file for Bluelog Live if (config.bluelive) { fprintf(infofile,"<div class=\"sideitem\">%s Version: %s%s</div>\n", APPNAME, VERSION, VER_MOD); fprintf(infofile,"<div class=\"sideitem\">Device: %s</div>\n", config.addr); fprintf(infofile,"<div class=\"sideitem\">Started: %s</div>\n", cur_time); // Think we are done with you now fclose(infofile); } // Log success to this point syslog(LOG_INFO,"Init OK!"); // Daemon switch if (config.daemon) daemonize(); else if (!config.quiet) #if defined PWNPAD printf("Close this window to end scan.\n"); #else printf("Hit Ctrl+C to end scan.\n"); #endif // Init result struct results = (inquiry_info*)malloc(max_results * sizeof(inquiry_info)); // Start scan, be careful with this infinite loop... for(;;) { // Flush results buffer memset(results, '\0', max_results * sizeof(inquiry_info)); // Scan and return number of results num_results = hci_inquiry(device, scan_window, max_results, NULL, &results, flags); // A negative number here means an error during scan if(num_results < 0) { // Increment error count error_count++; // Ignore occasional errors on Pwn Plug and OpenWRT #if !defined PWNPLUG || OPENWRT // All other platforms, print error and bail out syslog(LOG_ERR,"Received error from BlueZ!"); printf("Scan failed!\n"); // Check for kernel 3.0.x if (!strncmp("3.0.",sysinfo.release,4)) { printf("\n"); printf("-----------------------------------------------------\n"); printf("Device scanning failed, and you are running a 3.0.x\n"); printf("Linux kernel. This failure is probably due to the\n"); printf("following kernel bug:\n"); printf("\n"); printf("http://marc.info/?l=linux-kernel&m=131629118406044\n"); printf("\n"); printf("You will need to upgrade your kernel to at least the\n"); printf("the 3.1 series to continue.\n"); printf("-----------------------------------------------------\n"); } shut_down(1); #else // Exit on back to back errors if (error_count > 5) { printf("Scan failed!\n"); syslog(LOG_ERR,"BlueZ not responding, unrecoverable!"); shut_down(1); } // Otherwise, throttle back a bit, might help sleep(1); #endif } else { // Clear error counter error_count = 0; } // Check if we need to reset device cache if ((cache_index + num_results) >= MAX_DEV) { syslog(LOG_INFO,"Resetting device cache..."); memset(dev_cache, 0, sizeof(dev_cache)); cache_index = 0; } // Loop through results for (i = 0; i < num_results; i++) { // Return current MAC from struct ba2str(&(results+i)->bdaddr, addr); // Compare to device cache for (ri = 0; ri <= cache_index; ri++) { // Determine if device is already logged if (strcmp (addr, dev_cache[ri].priv_addr) == 0) { // This device has been seen before // Increment seen count, update printed time dev_cache[ri].seen++; strcpy(dev_cache[ri].time, get_localtime()); dev_cache[ri].missing_count = 0; // If we don't have a name, query again if ((dev_cache[ri].print == 3) && (dev_cache[ri].seen > config.retry_count)) { syslog(LOG_INFO,"Unable to find name for %s!", addr); dev_cache[ri].print = 1; } else if ((dev_cache[ri].print == 3) && (dev_cache[ri].seen < config.retry_count)) { // Query name strcpy(dev_cache[ri].name, namequery(&(results+i)->bdaddr)); // Did we get one? if (strcmp (dev_cache[ri].name, "VOID") != 0) { syslog(LOG_INFO,"Name retry for %s successful!", addr); // Force print dev_cache[ri].print = 1; } else syslog(LOG_INFO,"Name retry %i for %s failed!",dev_cache[ri].seen, addr); } // Amnesia mode if (config.amnesia >= 0) { // Find current epoch time epoch = time(NULL); if ((epoch - dev_cache[ri].epoch) >= (config.amnesia * 60)) { // Update epoch time dev_cache[ri].epoch = epoch; // Set device to print dev_cache[ri].print = 1; } } // This device is seen before, but has been away if (strcmp (dev_cache[ri].status, "gone") == 0) { dev_cache[ri].print = 1; strcpy(dev_cache[ri].status, "returned"); } // Unless we need to get printed, move to next result if (dev_cache[ri].print != 1) break; } else if (strcmp (dev_cache[ri].addr, "") == 0) { // Write new device MAC (visible and internal use) strcpy(dev_cache[ri].addr, addr); strcpy(dev_cache[ri].priv_addr, addr); // Query for name if (config.getname) strcpy(dev_cache[ri].name, namequery(&(results+i)->bdaddr)); else strcpy(dev_cache[ri].name, "IGNORED"); // Get time found strcpy(dev_cache[ri].time, get_localtime()); dev_cache[ri].epoch = time(NULL); // Class info dev_cache[ri].flags = (results+i)->dev_class[2]; dev_cache[ri].major_class = (results+i)->dev_class[1]; dev_cache[ri].minor_class = (results+i)->dev_class[0]; // Init misc variables dev_cache[ri].seen = 1; dev_cache[ri].missing_count = 0; strcpy(dev_cache[ri].status, "new"); // Increment index cache_index++; // If we have a device name, get printed if (strcmp (dev_cache[ri].name, "VOID") != 0) dev_cache[ri].print = 1; else { // Found with no name. // Print message to syslog, prevent printing, and move on syslog(LOG_INFO,"Device %s discovered with no name, will retry", dev_cache[ri].addr); dev_cache[ri].print = 3; break; } } // Ready to print? if (dev_cache[ri].print == 1) { // Encode MAC if (config.encode || config.obfuscate) { // Clear buffer memset(addr_buff, '\0', sizeof(addr_buff)); if (config.obfuscate) strcpy(addr_buff, mac_obfuscate(dev_cache[ri].priv_addr)); if (config.encode) strcpy(addr_buff, mac_encode(dev_cache[ri].priv_addr)); // Copy to cache strcpy(dev_cache[ri].addr, addr_buff); } // Print everything to console if verbose is on, optionally friendly class info if (config.verbose) { if (config.friendlyclass) { printf("[%s] %s,%s,%s,(%s) - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, device_class(dev_cache[ri].major_class,\ dev_cache[ri].minor_class), device_capability(dev_cache[ri].flags), dev_cache[ri].status); } else { printf("[%s] %s,%s,0x%02x%02x%02x - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class, dev_cache[ri].status); } } if (config.bluelive) { // Write result with live function live_entry(ri); } else if (config.bluepropro) { // Set output format for BlueProPro fprintf(outfile,"%s", dev_cache[ri].addr); fprintf(outfile,",0x%02x%02x%02x", dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class); fprintf(outfile,",%s\n", dev_cache[ri].name); } else { // Flush buffer memset(outbuffer, 0, sizeof(outbuffer)); // Print time first if enabled if (config.showtime) sprintf(outbuffer,"[%s],", dev_cache[ri].time); // Always output MAC sprintf(outbuffer+strlen(outbuffer),"%s", dev_cache[ri].addr); // Optionally output class if (config.showclass) sprintf(outbuffer+strlen(outbuffer),",0x%02x%02x%02x", dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class); // "Friendly" version of class info if (config.friendlyclass) sprintf(outbuffer+strlen(outbuffer),",%s,(%s)",\ device_class(dev_cache[ri].major_class, dev_cache[ri].minor_class),\ device_capability(dev_cache[ri].flags)); // Get manufacturer if (config.getmanufacturer) sprintf(outbuffer+strlen(outbuffer),",%s", mac_get_vendor(dev_cache[ri].priv_addr)); // Append the name if (config.getname) sprintf(outbuffer+strlen(outbuffer),",%s", dev_cache[ri].name); // Append the status if (config.status) sprintf(outbuffer+strlen(outbuffer)," - %s", dev_cache[ri].status); // Send buffer, else file. File needs newline if (config.syslogonly) syslog(LOG_INFO,"%s", outbuffer); else if (config.udponly) { // Append newline to socket, kind of hacky sprintf(outbuffer+strlen(outbuffer),"\n"); send_udp_msg(outbuffer); } else fprintf(outfile,"%s\n",outbuffer); } dev_cache[ri].print = 0; break; } // If we make it this far, it means we will check next stored device } // If there's a file open, write changes if (outfile != NULL) fflush(outfile); } // Now check if any devices are missing // Loop through the cache for (ri = 0; ri < cache_index; ri++) { for (i = 0; i <= num_results; i++) { // Return current MAC from struct ba2str(&(results+i)->bdaddr, addr); // Determine if device still present if (strcmp (addr, dev_cache[ri].priv_addr) == 0) { break; } // Device not found. if (i == num_results) { // The device is missing but not marked as gone -> it has just disappeared if (strcmp(dev_cache[ri].status, "gone") != 0) { // Devices aren't present every time. Wait a while before marking it gone if (dev_cache[ri].missing_count < 10) { dev_cache[ri].missing_count++; } else // It's really gone :( { strcpy(dev_cache[ri].status,"gone"); // Print to console if (config.verbose) { printf("[%s] %s,%s - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, dev_cache[ri].status); } // Flush buffer memset(exitbuffer, 0, sizeof(exitbuffer)); // Print time first if enabled if (config.showtime) sprintf(exitbuffer,"[%s],", dev_cache[ri].time); // Always output MAC sprintf(exitbuffer+strlen(exitbuffer),"%s", dev_cache[ri].addr); // Append the name if (config.getname) sprintf(exitbuffer+strlen(exitbuffer),",%s", dev_cache[ri].name); // Append the status if (config.status) sprintf(exitbuffer+strlen(exitbuffer)," - %s", dev_cache[ri].status); // Send buffer, else file. File needs newline if (config.syslogonly) syslog(LOG_INFO,"%s", exitbuffer); else if (config.udponly) { // Append newline to socket, kind of hacky sprintf(exitbuffer+strlen(exitbuffer),"\n"); send_udp_msg(exitbuffer); } else fprintf(outfile,"%s\n",exitbuffer); // If there's a file open, write changes if (outfile != NULL) fflush(outfile); } } } } } } // If we get here, shut down shut_down(0); // STFU return (1); }
void peisk_clUseBluetooth(char *device) { int opt,dd; char key[256], val[256]; PeisBluetoothAdaptor *adaptor = &peisk_bluetoothAdaptors[peisk_nBluetoothAdaptors]; adaptor->id = hci_devid(device); adaptor->outgoing.mode = 0; if(adaptor->id < 0) { perror(""); fprintf(stderr,"Warning, failed to open adaptor %s\n",device); return; } if(hci_devinfo(adaptor->id,&adaptor->info)) { perror(""); fprintf(stderr,"Failed to query adaptor %s\n",device); return; } printf("Current MTU ACL %d SCO %d\n",adaptor->info.acl_mtu,adaptor->info.sco_mtu); if(hci_devba(adaptor->id, &adaptor->addr) < 0) { perror(""); fprintf(stderr,"Failed to query address of %s\n",device); return; } dd = hci_open_dev(adaptor->id); opt = hci_test_bit(HCI_RAW,&adaptor->info.flags); /* Setting adaptor to RAW mode, needed for scanning (?) */ errno=0; if(ioctl(dd,HCISETRAW,opt) < 0) { if(errno == EACCES) { fprintf(stderr,"Warning, cannot gain RAW access to bluetooth device %s\n",device); /*return;*/ } } hci_close_dev(dd); adaptor->interfaceSocket = socket(AF_BLUETOOTH, SOCK_RAW,BTPROTO_HCI); if(adaptor->interfaceSocket < 0) { fprintf(stderr,"Error, cannot create RAW socket to bluetooth device %s, dropping it\n",device); return; } opt=1; if (setsockopt(adaptor->interfaceSocket, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) { perror("Can't enable data direction info"); return; } opt=1; if (setsockopt(adaptor->interfaceSocket, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) { perror("Can't enable time stamp"); return; } /* Setup filter */ struct hci_filter flt; hci_filter_clear(&flt); hci_filter_all_ptypes(&flt); hci_filter_all_events(&flt); if (setsockopt(adaptor->interfaceSocket, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("Can't set filter"); return; } /* Bind socket to the HCI device */ struct sockaddr_hci isock_addr; isock_addr.hci_family = AF_BLUETOOTH; isock_addr.hci_dev = adaptor->id; if (bind(adaptor->interfaceSocket, (struct sockaddr *) &isock_addr, sizeof(isock_addr)) < 0) { printf("Can't attach to device %s. %s(%d)\n", device, strerror(errno), errno); return; } printf("Successfully bound a RAW socket to %s\n",device); adaptor->name = strdup(device); adaptor->isScanning = 0; adaptor->nextScan = 0; peisk_nBluetoothAdaptors++; /* Give mac address of adaptor as value for the device tuple kernel.hciX */ sprintf(key,"kernel.%s",device); ba2str(&adaptor->addr, val); peisk_setStringTuple(key,val); /* Setup any L2CAP port for connections */ struct sockaddr_l2 listen_addr={0}; adaptor->listenSocket = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if(adaptor->listenSocket < 0) { fprintf(stderr,"peisk::warning - cannot create listening socket for %s\n",device); } else { adaptor->port = 1000; listen_addr.l2_family = AF_BLUETOOTH; listen_addr.l2_bdaddr = adaptor->addr; /* Brute force search until we find a free port we can use */ while(1) { listen_addr.l2_psm = adaptor->port; if(bind(adaptor->listenSocket, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) == 0) break; if(++adaptor->port > 32765) { adaptor->port=-1; close(adaptor->listenSocket); adaptor->listenSocket=-1; fprintf(stderr,"peisk::warning - cannot bind any port for %s\n",device); break; } } printf("Using bluetooth port %d\n",adaptor->port); if(adaptor->listenSocket != -1 && listen(adaptor->listenSocket, 1)) { adaptor->port=-1; close(adaptor->listenSocket); adaptor->listenSocket=-1; fprintf(stderr,"peisk::warning - cannot listen on %s\n",device); } if(adaptor->listenSocket != -1 && fcntl(adaptor->listenSocket,F_SETFL,O_NONBLOCK) == -1){ adaptor->port=-1; close(adaptor->listenSocket); adaptor->listenSocket=-1; fprintf(stderr,"peisk::warning - failed to set listening socket of %s non blocking\n",device); } /* if(adaptor->listenSocket != -1) { peisk_bluetooth_setMTU(adaptor->listenSocket); }*/ } /* Setup L2CAP port for hello messages */ struct sockaddr_l2 hello_addr={0}; adaptor->helloSocket = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); hello_addr.l2_family = AF_BLUETOOTH; hello_addr.l2_bdaddr = adaptor->addr; hello_addr.l2_psm = htobs(0x1001); if(adaptor->helloSocket != -1 && bind(adaptor->helloSocket, (struct sockaddr *)&hello_addr, sizeof(hello_addr))) { close(adaptor->helloSocket); adaptor->helloSocket = -1; printf("peisk::warning, could not bind L2CAP socket 0x7E15 on %s\nWe will not be bluetooth connectable\n",device); } if(adaptor->helloSocket != -1 && listen(adaptor->helloSocket, 1)) { printf("peisk::warning, failed to listen to L2CAP on %s\nWe will not be bluetooth connectable",device); close(adaptor->helloSocket); adaptor->helloSocket = -1; } if(adaptor->helloSocket != -1 && fcntl(adaptor->helloSocket,F_SETFL,O_NONBLOCK) == -1) { printf("peisk::warning, failed to set L2CAP socket on %s non blocking\nWe will not be bluetooth connectable",device); close(adaptor->helloSocket); adaptor->helloSocket = -1; } /* Mark adaptor as not having any pending hello's right now */ adaptor->pendingHelloFd = -1; printf("Listesting on %s: %02X:%02X:%02X:%02X:%02X:%02X;%d\n",device, adaptor->addr.b[5],adaptor->addr.b[4],adaptor->addr.b[3],adaptor->addr.b[2], adaptor->addr.b[1],adaptor->addr.b[0],adaptor->port); }
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); }
int main(int argc, char *argv[]) { struct sigaction sa; struct hci_dev_info di; struct hci_version ver; struct hci_filter flt; bdaddr_t bdaddr, master, slave; int need_raw; int dd, opt, dev = 0; bacpy(&slave, BDADDR_ANY); while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); if (dev < 0) { perror("Invalid device"); exit(1); } break; case 'h': default: usage(); exit(0); } } argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); exit(1); } str2ba(argv[0], &master); if (argc > 1) str2ba(argv[1], &slave); dd = hci_open_dev(dev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", dev, strerror(errno), errno); exit(1); } if (hci_devinfo(dev, &di) < 0) { fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } if (hci_read_local_version(dd, &ver, 1000) < 0) { fprintf(stderr, "Can't read version for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } if (ver.manufacturer != 10 || id2ver(ver.hci_rev) < 0) { fprintf(stderr, "Can't find sniffer at hci%d: %s (%d)\n", dev, strerror(ENOSYS), ENOSYS); hci_close_dev(dd); exit(1); } if (!bacmp(&di.bdaddr, BDADDR_ANY)) { if (hci_read_bd_addr(dd, &bdaddr, 1000) < 0) { fprintf(stderr, "Can't read address for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } } else bacpy(&bdaddr, &di.bdaddr); need_raw = !hci_test_bit(HCI_RAW, &di.flags); hci_filter_clear(&flt); hci_filter_set_ptype(HCI_ACLDATA_PKT, &flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_VENDOR, &flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { fprintf(stderr, "Can't set filter for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); if (need_raw) { if (ioctl(dd, HCISETRAW, 1) < 0) { fprintf(stderr, "Can't set raw mode on hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); exit(1); } } printf("CSR sniffer - Bluetooth packet analyzer ver %s\n", VERSION); if (need_raw) { if (ioctl(dd, HCISETRAW, 0) < 0) fprintf(stderr, "Can't clear raw mode on hci%d: %s (%d)\n", dev, strerror(errno), errno); } hci_close_dev(dd); return 0; }
int main(int argc, char **argv) { char *dst = NULL, *src = NULL; struct sigaction sa; int mode = NONE; int opt; while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) { switch(opt) { case 'l': mode = SHOW; detach = 0; break; case 's': mode = LISTEN; break; case 'c': mode = CONNECT; dst = strdup(optarg); break; case 'Q': mode = CONNECT; if (optarg) search_duration = atoi(optarg); break; case 'k': mode = KILL; detach = 0; dst = strdup(optarg); break; case 'K': mode = KILL; detach = 0; break; case 'i': src = strdup(optarg); break; case 'r': bnep_str2svc(optarg, &role); break; case 'd': bnep_str2svc(optarg, &service); break; case 'D': use_sdp = 0; break; case 'E': encrypt = 1; break; case 'S': secure = 1; break; case 'M': master = 1; break; case 'e': strcpy(netdev, optarg); break; case 'n': detach = 0; break; case 'p': if (optarg) persist = atoi(optarg); else persist = 5; break; case 'C': if (optarg) use_cache = atoi(optarg); else use_cache = 2; break; case 'P': pidfile = strdup(optarg); break; case 'z': cleanup = 1; break; case 'h': default: printf(main_help); exit(0); } } argc -= optind; argv += optind; optind = 0; if (bnep_init()) return -1; /* Check non daemon modes first */ switch (mode) { case SHOW: do_show(); return 0; case KILL: do_kill(dst); return 0; case NONE: printf(main_help); return 0; } /* Initialize signals */ memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); if (detach) { if (fork()) exit(0); /* Direct stdin,stdout,stderr to '/dev/null' */ { int fd = open("/dev/null", O_RDWR); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); } setsid(); chdir("/"); } openlog("pand", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); syslog(LOG_INFO, "Bluetooth PAN daemon version %s", VERSION); if (src) { src_dev = hci_devid(src); if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) { syslog(LOG_ERR, "Invalid source. %s(%d)", strerror(errno), errno); return -1; } } if (pidfile && write_pidfile()) return -1; if (dst) { /* Disable cache invalidation */ use_cache = 0; strncpy(cache.dst, dst, sizeof(cache.dst) - 1); str2ba(dst, &cache.bdaddr); cache.valid = 1; free(dst); } switch (mode) { case CONNECT: do_connect(); break; case LISTEN: do_listen(); break; } if (pidfile) unlink(pidfile); return 0; }
int main(int argc, char *argv[]) { int opt; int sec = BT_SECURITY_LOW; uint16_t mtu = 0; uint8_t dst_type = BDADDR_LE_PUBLIC; bool dst_addr_given = false; bdaddr_t src_addr, dst_addr; int dev_id = -1; int fd; sigset_t mask; struct client *cli; while ((opt = getopt_long(argc, argv, "+hvs:m:t:d:i:", main_options, NULL)) != -1) { switch (opt) { case 'h': usage(); return EXIT_SUCCESS; case 'v': verbose = true; break; case 's': if (strcmp(optarg, "low") == 0) sec = BT_SECURITY_LOW; else if (strcmp(optarg, "medium") == 0) sec = BT_SECURITY_MEDIUM; else if (strcmp(optarg, "high") == 0) sec = BT_SECURITY_HIGH; else { fprintf(stderr, "Invalid security level\n"); return EXIT_FAILURE; } break; case 'm': { int arg; arg = atoi(optarg); if (arg <= 0) { fprintf(stderr, "Invalid MTU: %d\n", arg); return EXIT_FAILURE; } if (arg > UINT16_MAX) { fprintf(stderr, "MTU too large: %d\n", arg); return EXIT_FAILURE; } mtu = (uint16_t)arg; break; } case 't': if (strcmp(optarg, "random") == 0) dst_type = BDADDR_LE_RANDOM; else if (strcmp(optarg, "public") == 0) dst_type = BDADDR_LE_PUBLIC; else { fprintf(stderr, "Allowed types: random, public\n"); return EXIT_FAILURE; } break; case 'd': if (str2ba(optarg, &dst_addr) < 0) { fprintf(stderr, "Invalid remote address: %s\n", optarg); return EXIT_FAILURE; } dst_addr_given = true; break; case 'i': dev_id = hci_devid(optarg); if (dev_id < 0) { perror("Invalid adapter"); return EXIT_FAILURE; } break; default: fprintf(stderr, "Invalid option: %c\n", opt); return EXIT_FAILURE; } } if (!argc) { usage(); return EXIT_SUCCESS; } argc -= optind; argv += optind; optind = 0; if (argc) { usage(); return EXIT_SUCCESS; } if (dev_id == -1) bacpy(&src_addr, BDADDR_ANY); else if (hci_devba(dev_id, &src_addr) < 0) { perror("Adapter not available"); return EXIT_FAILURE; } if (!dst_addr_given) { fprintf(stderr, "Destination address required!\n"); return EXIT_FAILURE; } mainloop_init(); fd = l2cap_le_att_connect(&src_addr, &dst_addr, dst_type, sec); if (fd < 0) return EXIT_FAILURE; cli = client_create(fd, mtu); if (!cli) { close(fd); return EXIT_FAILURE; } if (mainloop_add_fd(fileno(stdin), EPOLLIN | EPOLLRDHUP | EPOLLHUP | EPOLLERR, prompt_read_cb, cli, NULL) < 0) { fprintf(stderr, "Failed to initialize console\n"); return EXIT_FAILURE; } sigemptyset(&mask); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); mainloop_set_signal(&mask, signal_cb, NULL, NULL); print_prompt(); mainloop_run(); printf("\n\nShutting down...\n"); client_destroy(cli); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { int opt, sock, dev_id, lap = 0, uap = 0, delay = 5; int have_lap = 0; int have_uap = 0; int afh_enabled = 0; uint8_t mode, afh_map[10]; char *end, ubertooth_device = -1; char *bt_dev = "hci0"; char addr[19] = { 0 }; struct libusb_device_handle *devh = NULL; uint32_t clock; uint16_t accuracy, handle, offset; bdaddr_t bdaddr; btbb_piconet *pn; struct hci_dev_info di; int cc = 0; pn = btbb_piconet_new(); while ((opt=getopt(argc,argv,"hl:u:U:e:d:ab:w:")) != EOF) { switch(opt) { case 'l': lap = strtol(optarg, &end, 16); if (end != optarg) { ++have_lap; } break; case 'u': uap = strtol(optarg, &end, 16); if (end != optarg) { ++have_uap; } break; case 'U': ubertooth_device = atoi(optarg); break; case 'e': max_ac_errors = atoi(optarg); break; case 'd': dumpfile = fopen(optarg, "w"); if (dumpfile == NULL) { perror(optarg); return 1; } break; case 'a': afh_enabled = 1; break; case 'b': bt_dev = optarg; if (bt_dev == NULL) { perror(optarg); return 1; } break; case 'w': //wait delay = atoi(optarg); break; case 'h': default: usage(); return 1; } } dev_id = hci_devid(bt_dev); sock = hci_open_dev(dev_id); hci_read_clock(sock, 0, 0, &clock, &accuracy, 0); if ((have_lap != 1) || (have_uap != 1)) { printf("No address given, reading address from device\n"); hci_read_bd_addr(sock, &bdaddr, 0); lap = bdaddr.b[0] | bdaddr.b[1] << 8 | bdaddr.b[2] << 16; btbb_init_piconet(pn, lap); uap = bdaddr.b[3]; btbb_piconet_set_uap(pn, uap); printf("LAP=%06x UAP=%02x\n", lap, uap); } else if (have_lap && have_uap) { btbb_init_piconet(pn, lap); btbb_piconet_set_uap(pn, uap); printf("Address given, assuming address is remote\n"); sprintf(addr, "00:00:%02X:%02X:%02X:%02X", uap, (lap >> 16) & 0xFF, (lap >> 8) & 0xFF, lap & 0xFF ); str2ba(addr, &bdaddr); printf("Address: %s\n", addr); if (hci_devinfo(dev_id, &di) < 0) { perror("Can't get device info"); return 1; } if (hci_create_connection(sock, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); return 1; } sleep(1); cc = 1; if (hci_read_clock_offset(sock, handle, &offset, 1000) < 0) { perror("Reading clock offset failed"); } clock += offset; //Experimental AFH map reading from remote device if(afh_enabled) { if(hci_read_afh_map(sock, handle, &mode, afh_map, 1000) < 0) { perror("HCI read AFH map request failed"); //exit(1); } if(mode == 0x01) { btbb_piconet_set_afh_map(pn, afh_map); btbb_print_afh_map(pn); } else { printf("AFH disabled.\n"); afh_enabled = 0; } } if (cc) { usleep(10000); hci_disconnect(sock, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); } } else {
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); }