void scan(int argc, char *argv[]) { IPv4Address ip(argv[1]); // Resolve the interface which will be our gateway NetworkInterface iface(ip); cout << "Sniffing on interface: " << iface.name() << endl; // 300 bytes are enough to receive SYNs and RSTs. SnifferConfiguration config; config.set_snap_len(300); Sniffer sniffer(iface.name(), config); sniffer_data data(&sniffer, argv[1]); pthread_t thread; // Launch our sniff thread. pthread_create(&thread, 0, thread_proc, &data); // Consume arguments argv += 2; argc -= 2; // Start sending SYNs to port. send_syns(iface, ip, vector<string>(argv, argv + (argc))); // Wait for our sniffer. void *dummy; pthread_join(thread, &dummy); }
Sniffer::Sniffer(const string& device, unsigned max_packet_size, bool promisc, const string& filter, bool rfmon) { SnifferConfiguration configuration; configuration.set_snap_len(max_packet_size); configuration.set_promisc_mode(promisc); configuration.set_filter(filter); configuration.set_rfmon(rfmon); char error[PCAP_ERRBUF_SIZE]; pcap_t* phandle = pcap_create(TINS_PREFIX_INTERFACE(device).c_str(), error); if (!phandle) { throw runtime_error(error); } set_pcap_handle(phandle); // Set the netmask if we are able to find it. bpf_u_int32 ip, if_mask; if (pcap_lookupnet(TINS_PREFIX_INTERFACE(device).c_str(), &ip, &if_mask, error) == 0) { set_if_mask(if_mask); } // Configure the sniffer's attributes prior to activation. configuration.configure_sniffer_pre_activation(*this); // Finally, activate the pcap. In case of error throw runtime_error if (pcap_activate(get_pcap_handle()) < 0) { throw pcap_error(pcap_geterr(get_pcap_handle())); } // Configure the sniffer's attributes after activation. configuration.configure_sniffer_post_activation(*this); }
result_type trace() { // ICMPs that aren't sent from us. SnifferConfiguration config; config.set_snap_len(500); config.set_promisc_mode(false); config.set_filter( "ip proto \\icmp and not src host " + iface.addresses().ip_addr.to_string()); Sniffer sniffer(iface.name(), config); PacketSender sender; // Create our handler auto handler = std::bind( &Traceroute::sniff_callback, this, std::placeholders::_1 ); // We're running running = true; // Start the sniff thread std::thread sniff_thread( &Sniffer::sniff_loop<decltype(handler)>, &sniffer, handler, 0 ); send_packets(sender); sniff_thread.join(); // Clear our results and return what we've found return std::move(results); }
PDU& PacketSenderGeneric::send_recv(PDU& spdu, SharedSender& shared_sender, const NetworkInterface& iface, bool promisc, double* rdelay, double* edelay) { //wait for previous packet to receive response (TODO: not ideal, plan future change) while (sent_pdu) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } sent_pdu = spdu.clone(); //start sniff task SnifferConfiguration config; config.set_promisc_mode(promisc); config.set_snap_len(65535); config.set_timeout(10); //Critical section SHARED_SNIFFER_MUTEX.lock(); Sniffer sniffer{ iface.name(), config }; SHARED_SNIFFER_MUTEX.unlock(); bool compute_delay = true; if (!rdelay) compute_delay = false; std::future<void> fresp(std::async(std::launch::async, &PacketSenderGeneric::sniff_task, this, &sniffer, compute_delay)); //send packet std::clock_t effective_sent_time = std::clock(); std::cout << "Registering packet to send !" << std::endl; shared_sender.register_packet(sent_pdu, NetworkInterface(iface)); //std::cout << "waiting for max " << timeout << "..." << std::endl; std::future_status status = fresp.wait_for(std::chrono::seconds(timeout)); //raise exception in case of timeout if (status == std::future_status::timeout) { sniffer.stop_sniff(); sent_pdu = NULL; throw timeout_elapsed(); } else if (status == std::future_status::deferred) std::cout << "DEBUG: packet sniffing deffered... shouldn't happen"; //Treat response packet if (edelay) *edelay = ((std::clock() - effective_sent_time) / (double)CLOCKS_PER_SEC) * 1000; if (rdelay) { *rdelay = response_delay; } PDU& response(*this->response_pdu); //Clean sent_pdu = NULL; response_delay = NULL; //response_pdu = NULL; return response; }
int main(int argc, char *argv[]) { if(argc != 2) { std::cout << "Usage: " << *argv << " <DEVICE>\n"; return 1; } // Only sniff beacons SnifferConfiguration config; config.set_snap_len(2000); config.set_promisc_mode(true); config.set_filter("wlan type mgt subtype beacon"); Sniffer sniffer(argv[1], config); sniffer.sniff_loop(handler); }