void IPTest::test_equals(const IP &ip1, const IP &ip2) { EXPECT_EQ(ip1.dst_addr(), ip2.dst_addr()); EXPECT_EQ(ip1.src_addr(), ip2.src_addr()); EXPECT_EQ(ip1.id(), ip2.id()); EXPECT_EQ(ip1.frag_off(), ip2.frag_off()); EXPECT_EQ(ip1.tos(), ip2.tos()); EXPECT_EQ(ip1.ttl(), ip2.ttl()); EXPECT_EQ(ip1.version(), ip2.version()); EXPECT_EQ((bool)ip1.inner_pdu(), (bool)ip2.inner_pdu()); }
// 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); }
TEST_F(IPTest, DefaultConstructor) { IP ip; EXPECT_EQ(ip.dst_addr(), "0.0.0.0"); EXPECT_EQ(ip.src_addr(), "0.0.0.0"); EXPECT_EQ(ip.version(), 4); EXPECT_EQ(ip.id(), 1); EXPECT_EQ(ip.pdu_type(), PDU::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; }
TEST_F(IPTest, SrcIPInt) { IP ip; ip.src_addr("192.155.32.10"); EXPECT_EQ(ip.src_addr(), "192.155.32.10"); }
TEST_F(IPTest, SrcIPString) { IP ip; string string_ip("192.155.32.10"); ip.src_addr(string_ip); EXPECT_EQ(ip.src_addr(), IPv4Address(string_ip)); }
static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) { Mode mode = ((nf_data*)data)->mode; u_int32_t id = ntohl(nfq_get_msg_packet_hdr(nfa)->packet_id); unsigned char *packet; int size = nfq_get_payload(nfa, &packet); std::vector<uint8_t> result; u_int32_t verdict = NF_ACCEPT; try { IP ip = IP(packet, size); //cout << ip.src_addr() << " -> " << ip.dst_addr() << endl; NetworkInterface interface(ip.dst_addr()); IP::address_type interface_addr = interface.addresses().ip_addr; RR *rr = ip.find_pdu<RR>(); if (mode == ROUTER) { if (rr != 0) { //cout << "Adding to existing RR" << endl; } else { create_rr(ip); rr = ip.find_pdu<RR>(); if (is_spoof && ip.src_addr() == IP::address_type("192.168.30.10")) { rr->route().push_back(RREntry(IP::address_type("192.168.100.20"), 42, 42)); } } // TODO Figure out what the magic numbers are for the source address RREntry src_hop(ip.src_addr(), 0x0, 0x0); RREntry last_hop = src_hop; if (rr != 0 && rr->route().size() >= 1) last_hop = rr->route().back(); AITF_packet aitf; if (should_intercept(ip, rr, &aitf)) { //cout << "Intercepting packet" << endl; send_AITF_message(aitf, IP::address_type("192.168.10.100")); verdict = NF_DROP; } else if (is_blocked(last_hop, ip.dst_addr()) || (is_shadow && rr->route().size() > 1 && is_blocked(src_hop, ip.dst_addr()))) { //cout << "Packet blocked" << endl; verdict = NF_DROP; } else if (hosts.isLegacyHost(ip.dst_addr())) { //cout << "Legacy host detected" << endl; if (rr != 0) { //print_route(rr->route()); strip_rr(ip, *rr); } else { //cout << "No RR table present" << endl; } } else { NetworkInterface interface(ip.dst_addr()); rr->route().push_back(RREntry(interface_addr, hash_for_destination(ip.dst_addr(), 0), hash_for_destination(ip.dst_addr(), 1))); if (rr->route().size() > rr->route_capacity()) { //cout << "RR table filled. Dropping packet." << endl; verdict = NF_DROP; } //else print_route(rr->route()); } } else if (mode == HOST) { if (rr != 0) { // Check if this is a bad packet // TODO don't hard code attacker ip addresses bool is_bad = false; try { UDP udp(&rr->payload()[0], rr->payload().size()); RawPDU* raw = udp.find_pdu<RawPDU>(); if (raw != 0) { is_bad = raw->payload()[0] == 1; } } catch (malformed_packet e) { } if (is_bad && is_victim) { if (!last_event_set) { printf("Attack detected\n"); gettimeofday(&last_event, NULL); last_event_set = true; event_delay = 500000; } else { struct timeval now; gettimeofday(&now, NULL); if ((now.tv_sec - last_event.tv_sec) * 1000000 + now.tv_usec - last_event.tv_usec > event_delay) { printf("Enforce sent\n"); print_route(rr->route()); vector<RRFilter> filters; filters.push_back(RRFilter(is_wildcard ? 1 : 0, ip.src_addr(), 0x0, 0x0)); for (int i = 0; i < rr->route().size(); i++) { const RREntry& entry = rr->route().at(i); filters.push_back(RRFilter(is_wildcard ? 1 : 0, entry.address(), entry.random_number_1(), entry.random_number_2())); } AITF_packet enforce(0, 0, 0, 1, filters, IP::address_type("192.168.10.10"), filters.size()); send_AITF_message(enforce, IP::address_type("192.168.10.100")); last_event = now; event_delay = is_aggressive ? 1000000 : 10000000; } } } //print_route(rr->route()); strip_rr(ip, *rr); } else { //cout << "No RR table present" << endl; } } result = ip.serialize(); //cout << endl; } catch (malformed_packet e) { cout << "malformed packet " << e.what() << endl; } return nfq_set_verdict(qh, id, verdict, verdict == NF_DROP ? 0 : result.size(), verdict == NF_DROP ? 0 : &result[0]); }