1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Modified IPv4Address interface and fixed some tests.

This commit is contained in:
Matias Fontanini
2012-08-15 08:36:59 -03:00
parent 6fd0c14b45
commit 68ab7b094a
4 changed files with 75 additions and 67 deletions

View File

@@ -20,12 +20,16 @@
*/ */
#include <iostream> #include <iostream>
#include <iomanip>
#include <vector>
#include <string> #include <string>
#include <cstdlib> #include <cstdlib>
#include <pthread.h> #include <pthread.h>
#include <tins/ip.h> #include <tins/ip.h>
#include <tins/tcp.h> #include <tins/tcp.h>
#include <tins/ipaddress.h>
#include <tins/ethernetII.h> #include <tins/ethernetII.h>
#include <tins/network_interface.h>
#include <tins/sniffer.h> #include <tins/sniffer.h>
#include <tins/utils.h> #include <tins/utils.h>
#include <tins/packetsender.h> #include <tins/packetsender.h>
@@ -34,97 +38,101 @@
using namespace std; using namespace std;
using namespace Tins; using namespace Tins;
typedef std::pair<Sniffer*, std::string> sniffer_data;
/* Our scan handler. This will receive SYNs and RSTs and inform us /* Our scan handler. This will receive SYNs and RSTs and inform us
* the scanned port's status. * the scanned port's status.
*/ */
struct ScanHandler { bool handler(PDU *pdu) {
bool operator() (PDU *pdu) { TCP *tcp = pdu->find_inner_pdu<TCP>();
TCP *tcp = (pdu->find_inner_pdu<TCP>(PDU::TCP)); if(tcp) {
if(tcp) { // Ok, it's a TCP PDU. Is RST flag on? Then port is closed.
// Ok, it's a TCP PDU. Is RST flag on? Then port is closed. if(tcp->get_flag(TCP::RST)) {
if(tcp->get_flag(TCP::RST)) // This indicates we should stop sniffing.
cout << "Port: " << tcp->sport() << " closed\n"; if(tcp->get_flag(TCP::SYN))
// Is SYN flag on? Then port is open! return false;
else if(tcp->get_flag(TCP::SYN)) cout << "Port: " << setw(5) << tcp->sport() << " closed\n";
cout << "Port: " << tcp->sport() << " open\n";
} }
return true; // Is SYN flag on? Then port is open!
else if(tcp->get_flag(TCP::SYN) && tcp->get_flag(TCP::ACK))
cout << "Port: " << setw(5) << tcp->sport() << " open\n";
} }
}; return true;
}
Sniffer *sniffer;
// Send syns to the given ip address, using the destination ports provided. // Send syns to the given ip address, using the destination ports provided.
void send_syns(const string &iface, uint32_t dest_ip, int argc, char *argv[]) { void send_syns(const NetworkInterface &iface, IPv4Address dest_ip, const vector<string> &ips) {
uint32_t own_ip; // Retrieve the addresses.
// Resolve our ip on that interface. NetworkInterface::Info info = iface.addresses();
if(!Utils::interface_ip(iface, own_ip) && cout << "Error obtaining interface ip.\n")
return;
PacketSender sender; PacketSender sender;
TCP *tcp = new TCP(); TCP *tcp = new TCP();
// Allocate the IP PDU // Allocate the IP PDU
IP ip(dest_ip, own_ip, tcp); IP ip(dest_ip, info.ip_addr, tcp);
// Set the SYN flag on. // Set the SYN flag on.
tcp->set_flag(TCP::SYN, 1); tcp->set_flag(TCP::SYN, 1);
// Just some arbitrary port. // Just some arbitrary port.
tcp->sport(1337); tcp->sport(1337);
while(argc--) { cout << "Sending SYNs..." << endl;
for(vector<string>::const_iterator it = ips.begin(); it != ips.end(); ++it) {
// Set the new port and send the packet! // Set the new port and send the packet!
uint32_t port = atoi(*(argv++)); tcp->dport(atoi(it->c_str()));
tcp->dport(port);
sender.send(&ip); 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(iface, info.hw_addr, info.hw_addr, ip.clone_pdu());
sender.send(&eth);
} }
void *thread_proc(void *param) { void *thread_proc(void *param) {
// IP address is our parameter. // IP address is our parameter.
string *data = (string*)param; sniffer_data *data = (sniffer_data*)param;
// The scan handler. Sniffer *sniffer = data->first;
ScanHandler handler; sniffer->set_filter("tcp and ip src " + data->second + " and tcp[tcpflags] & (tcp-rst|tcp-syn) != 0");
// The required subclass of AbstractSnifferHandler which will serve as
// a proxy to our handler.
AbstractSnifferHandler *my_handler = new SnifferHandler<ScanHandler>(&handler);
sniffer->set_filter("tcp and ip src " + *data + " and tcp[tcpflags] & (tcp-rst|tcp-syn) != 0");
// Sniff loop. Only sniff TCP PDUs comming from the given IP and have either RST or SYN flag on. // Sniff loop. Only sniff TCP PDUs comming from the given IP and have either RST or SYN flag on.
sniffer->sniff_loop(my_handler); sniffer->sniff_loop(handler);
delete my_handler;
return 0; return 0;
} }
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.
Sniffer sniffer(iface.name(), 300);
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);
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if(argc < 3 && cout << "Usage: " << *argv << " <IPADDR> <port1> [port2] [port3]\n") if(argc < 3 && cout << "Usage: " << *argv << " <IPADDR> <port1> [port2] [port3]\n")
return 1; return 1;
uint32_t ip;
try { try {
// Resolve the ip address scan(argc, argv);
ip = Utils::resolve_ip(argv[1]);
} }
catch(...) { catch(std::runtime_error &ex) {
cout << "IP address is not valid.\n"; cout << "Error - " << ex.what() << endl;
return 2;
} }
// Resolve the interface which will be our gateway
string iface = Utils::interface_from_ip(ip);
if(!iface.size() && cout << "Could not locate gateway interface for given ip address\n")
return 3;
// Allocate our sniffer. 300 bytes are enough to receive SYNs and RSTs.
sniffer = new Sniffer(iface, 300);
string ip_string = argv[1];
pthread_t thread;
// Launch our sniff thread.
pthread_create(&thread, 0, thread_proc, &ip_string);
// Start sending SYNs to port.
send_syns(iface, ip, argc - 2, argv + 2);
// Give it some time...
sleep(5);
// Ok, we kill our sniffer.
pthread_cancel(thread);
delete sniffer;
} }

View File

@@ -58,8 +58,8 @@ IPv4Address::operator std::string() const {
return Utils::ip_to_string(ip_addr); return Utils::ip_to_string(ip_addr);
} }
bool IPv4Address::operator==(const std::string &rhs) const { std::string IPv4Address::to_string() const {
return ip_addr == Utils::ip_to_int(rhs); return Utils::ip_to_string(ip_addr);
} }
uint32_t IPv4Address::ip_to_int(const string &ip) { uint32_t IPv4Address::ip_to_int(const string &ip) {

View File

@@ -51,8 +51,8 @@ void ARPTest::test_equals(const ARP &arp1, const ARP &arp2) {
TEST_F(ARPTest, DefaultContructor) { TEST_F(ARPTest, DefaultContructor) {
ARP arp; ARP arp;
EXPECT_EQ(arp.target_ip_addr(), 0); EXPECT_EQ(arp.target_ip_addr(), IPv4Address());
EXPECT_EQ(arp.sender_ip_addr(), 0); EXPECT_EQ(arp.sender_ip_addr(), IPv4Address());
EXPECT_EQ(arp.target_hw_addr(), empty_addr); EXPECT_EQ(arp.target_hw_addr(), empty_addr);
EXPECT_EQ(arp.target_hw_addr(), empty_addr); EXPECT_EQ(arp.target_hw_addr(), empty_addr);
EXPECT_EQ(arp.pdu_type(), PDU::ARP); EXPECT_EQ(arp.pdu_type(), PDU::ARP);

View File

@@ -24,8 +24,8 @@ const uint8_t IPTest::expected_packet[] = { '(', '\x7f', '\x00', ' ',
TEST_F(IPTest, DefaultConstructor) { TEST_F(IPTest, DefaultConstructor) {
IP ip; IP ip;
EXPECT_EQ(ip.dst_addr(), 0); EXPECT_EQ(ip.dst_addr(), IPv4Address());
EXPECT_EQ(ip.src_addr(), 0); EXPECT_EQ(ip.src_addr(), IPv4Address());
EXPECT_EQ(ip.version(), 4); EXPECT_EQ(ip.version(), 4);
EXPECT_EQ(ip.id(), 1); EXPECT_EQ(ip.id(), 1);
EXPECT_EQ(ip.pdu_type(), PDU::IP); EXPECT_EQ(ip.pdu_type(), PDU::IP);