void send_packets(PacketSender& sender) { // ICMPs are icmp-requests by default IP ip = IP(addr, iface.addresses().ip_addr) / ICMP(); ICMP& icmp = ip.rfind_pdu<ICMP>(); icmp.sequence(sequence); // We'll find at most 20 hops. for (auto i = 1; i <= 20; ++i) { // Set this ICMP id icmp.id(i); // Set the time-to-live option ip.ttl(i); // Critical section { lock_guard<mutex> _(lock); ttls[i] = i; } sender.send(ip); // Give it a little time sleep_for(milliseconds(100)); } running = false; sender.send(ip); }
// Send syns to the given ip address, using the destination ports provided. void send_syns(const NetworkInterface &iface, IPv4Address dest_ip, const vector<string> &ips) { // Retrieve the addresses. NetworkInterface::Info info = iface.addresses(); PacketSender sender; // Allocate the IP PDU IP ip = IP(dest_ip, info.ip_addr) / TCP(); // Get the reference to the TCP PDU TCP &tcp = ip.rfind_pdu<TCP>(); // Set the SYN flag on. tcp.set_flag(TCP::SYN, 1); // Just some random port. tcp.sport(1337); cout << "Sending SYNs..." << endl; for(vector<string>::const_iterator it = ips.begin(); it != ips.end(); ++it) { // Set the new port and send the packet! tcp.dport(atoi(it->c_str())); sender.send(ip); } // Wait 1 second. sleep(1); /* Special packet to indicate that we're done. This will be sniffed * by our function, which will in turn return false. */ tcp.set_flag(TCP::RST, 1); // Pretend we're the scanned host... ip.src_addr(dest_ip); // We use an ethernet pdu, otherwise the kernel will drop it. EthernetII eth = EthernetII(info.hw_addr, info.hw_addr) / ip; sender.send(eth, iface); }
void test2_sendpkt() { PacketSender sender; IP pkt = IP("192.168.0.1") / TCP(22) / RawPDU(randomStr().c_str()); std::cout << std::endl; for (;;) { sender.send(pkt); std::cout << "."; } }
void send_packets(PacketSender &sender) { // ICMPs are icmp-requests by default IP ip = IP(addr, iface.addresses().ip_addr) / ICMP(); // We'll find at most 10 hops. for(auto i = 1; i <= 10; ++i) { // Set this "unique" id ip.id(i); // Set the time-to-live option ip.ttl(i); // Critical section { std::lock_guard<std::mutex> _(lock); ttls[i] = i; } sender.send(ip); // Give him a little time std::this_thread::sleep_for(std::chrono::milliseconds(100)); } running = false; sender.send(ip); }
bool callback(const PDU &pdu) { // The packet probably looks like this: // // EthernetII / IP / UDP / RawPDU // // So we retrieve each layer, and construct a // DNS PDU from the RawPDU layer contents. EthernetII eth = pdu.rfind_pdu<EthernetII>(); IP ip = eth.rfind_pdu<IP>(); UDP udp = ip.rfind_pdu<UDP>(); DNS dns = udp.rfind_pdu<RawPDU>().to<DNS>(); // Is it a DNS query? if(dns.type() == DNS::QUERY) { // Let's see if there's any query for an "A" record. for(const auto &query : dns.queries()) { if(query.type() == DNS::A) { // Here's one! Let's add an answer. dns.add_answer( DNS::Resource( query.dname(), "127.0.0.1", DNS::A, query.query_class(), // 777 is just a random TTL 777 ) ); } } // Have we added some answers? if(dns.answers_count() > 0) { // It's a response now dns.type(DNS::RESPONSE); // Recursion is available(just in case) dns.recursion_available(1); // Build our packet auto pkt = EthernetII(eth.src_addr(), eth.dst_addr()) / IP(ip.src_addr(), ip.dst_addr()) / UDP(udp.sport(), udp.dport()) / dns; // Send it! sender.send(pkt); } } return true; }