int btbb_pcap_append_packet(btbb_pcap_handle * h, const uint64_t ns, const int8_t sigdbm, const int8_t noisedbm, const uint32_t reflap, const uint8_t refuap, const btbb_packet *pkt) { if (h && h->dumper) { uint16_t flags = BREDR_DEWHITENED | BREDR_SIGPOWER_VALID | ((noisedbm < sigdbm) ? BREDR_NOISEPOWER_VALID : 0) | ((reflap != LAP_ANY) ? BREDR_REFLAP_VALID : 0) | ((refuap != UAP_ANY) ? BREDR_REFUAP_VALID : 0); uint32_t caplen = (uint32_t) btbb_packet_get_payload_length(pkt); uint8_t payload_bytes[caplen]; btbb_get_payload_packed( pkt, (char *) &payload_bytes[0] ); caplen = MIN(BREDR_MAX_PAYLOAD, caplen); pcap_bredr_packet pcap_pkt; assemble_pcapng_bredr_packet( &pcap_pkt, 0, ns, caplen, btbb_packet_get_channel(pkt), sigdbm, noisedbm, btbb_packet_get_ac_errors(pkt), btbb_packet_get_transport(pkt), btbb_packet_get_modulation(pkt), 0, /* TODO: corrected header bits */ 0, /* TODO: corrected payload bits */ btbb_packet_get_lap(pkt), reflap, refuap, btbb_packet_get_header_packed(pkt), flags, payload_bytes ); pcap_dump((u_char *)h->dumper, &pcap_pkt.pcap_header, (u_char *)&pcap_pkt.bredr_bb_header); return 0; } return -PCAP_INVALID_HANDLE; }
/* 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); }