From fc0ccffe181068a1f3df38617861ec5f52553c34 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Wed, 12 Sep 2012 23:02:53 -0300 Subject: [PATCH] Modified PacketWriter interface to take references instead of pointers. --- include/packet_writer.h | 28 ++++++++++++++++++++++------ include/tcp_stream.h | 20 ++++++++++++++++++++ include/utils.h | 17 ++++++++++++++++- src/packet_writer.cpp | 4 ++-- src/utils.cpp | 15 ++++++++++++++- 5 files changed, 74 insertions(+), 10 deletions(-) diff --git a/include/packet_writer.h b/include/packet_writer.h index 403a0e3..ad69f45 100644 --- a/include/packet_writer.h +++ b/include/packet_writer.h @@ -22,8 +22,9 @@ #ifndef TINS_PACKET_WRITER_H #define TINS_PACKET_WRITER_H -#include #include +#include +#include namespace Tins { class PDU; @@ -61,7 +62,7 @@ public: /** * \brief Writes a PDU to this file. */ - void write(PDU *pdu); + void write(PDU &pdu); /** * \brief Writes all the PDUs in the range [start, end) @@ -69,15 +70,30 @@ public: * to be written. * \param end A forward iterator pointing to one past the last * PDU in the range. - * \return ForwardIterator which will be a copy of end. */ template - ForwardIterator write(ForwardIterator start, ForwardIterator end) { + void write(ForwardIterator start, ForwardIterator end) { + typedef typename std::iterator_traits::value_type value_type; + typedef derefer deref_type; + while(start != end) - write(*start++); - return start; + write(deref_type::deref(*start++)); } private: + template + struct derefer { + static T &deref(T &value) { + return value; + } + }; + + template + struct derefer { + static T &deref(T *value) { + return *value; + } + }; + // You shall not copy PacketWriter(const PacketWriter&); PacketWriter& operator=(const PacketWriter&); diff --git a/include/tcp_stream.h b/include/tcp_stream.h index 2db935c..1a28b83 100644 --- a/include/tcp_stream.h +++ b/include/tcp_stream.h @@ -212,6 +212,20 @@ public: */ template void follow_streams(BaseSniffer &sniffer, DataFunctor data_fun, EndFunctor end_fun); + + /** + * \brief Starts following TCP streams. + * + * The template functor must accept a TCPStream& as argument, which + * will point to the stream which has been modified. + * + * \param sniffer The sniffer which will be used to sniff PDUs. + * \param data_fun The function which will be called whenever one of + * the peers in a connection sends data. + * closed. + */ + template + void follow_streams(BaseSniffer &sniffer, DataFunctor data_fun); private: typedef std::map sessions_type; @@ -228,6 +242,7 @@ private: template bool callback(PDU &pdu, const DataFunctor &fun, const EndFunctor &end_fun); + static void dummy_function(TCPStream&) { } sessions_type sessions; uint64_t last_identifier; @@ -240,6 +255,11 @@ void TCPStreamFollower::follow_streams(BaseSniffer &sniffer, DataFunctor data_fu sniffer.sniff_loop(make_sniffer_handler(&proxy, &proxy_type::callback)); } +template +void TCPStreamFollower::follow_streams(BaseSniffer &sniffer, DataFunctor data_fun) { + return follow_streams(sniffer, data_fun, dummy_function); +} + template bool TCPStreamFollower::callback(PDU &pdu, const DataFunctor &data_fun, const EndFunctor &end_fun) { IP *ip = pdu.find_pdu(); diff --git a/include/utils.h b/include/utils.h index 3c3bc80..a5db817 100644 --- a/include/utils.h +++ b/include/utils.h @@ -80,7 +80,8 @@ namespace Tins { */ IPv4Address resolve_ip(const std::string &to_resolve); - /** \brief Resolves the hardware address for a given ip. + /** + * \brief Resolves the hardware address for a given ip. * * \param iface The interface in which the packet will be sent. * \param ip The ip to resolve, in integer format. @@ -91,6 +92,20 @@ namespace Tins { */ bool resolve_hwaddr(const NetworkInterface &iface, IPv4Address ip, HWAddress<6> *address, PacketSender &sender); + + /** + * \brief Resolves the hardware address for a given ip. + * + * If the address can't be resolved, a std::runtime_error + * exception is thrown. + * + * \param iface The interface in which the packet will be sent. + * \param ip The ip to resolve, in integer format. + * \param sender The sender to use to send and receive the ARP requests. + * \return HWAddress<6> containing the resolved hardware address. + */ + HWAddress<6> resolve_hwaddr(const NetworkInterface &iface, + IPv4Address ip, PacketSender &sender); /** \brief List all network interfaces. * diff --git a/src/packet_writer.cpp b/src/packet_writer.cpp index 8c421e8..879136a 100644 --- a/src/packet_writer.cpp +++ b/src/packet_writer.cpp @@ -44,8 +44,8 @@ PacketWriter::~PacketWriter() { pcap_close(handle); } -void PacketWriter::write(PDU *pdu) { - PDU::serialization_type buffer = pdu->serialize(); +void PacketWriter::write(PDU &pdu) { + PDU::serialization_type buffer = pdu.serialize(); struct timeval tm; gettimeofday(&tm, 0); struct pcap_pkthdr header = { diff --git a/src/utils.cpp b/src/utils.cpp index f25cf1a..a4b05e7 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -32,7 +32,6 @@ #include "utils.h" #include "pdu.h" #include "ip.h" -#include "icmp.h" #include "arp.h" #include "endianness.h" #include "network_interface.h" @@ -119,6 +118,20 @@ bool Utils::resolve_hwaddr(const NetworkInterface &iface, IPv4Address ip, return false; } +HWAddress<6> Utils::resolve_hwaddr(const NetworkInterface &iface, IPv4Address ip, PacketSender &sender) +{ + IPv4Address my_ip; + NetworkInterface::Info info(iface.addresses()); + std::auto_ptr packet(ARP::make_arp_request(iface, ip, info.ip_addr, info.hw_addr)); + std::auto_ptr response(sender.send_recv(*packet)); + if(response.get()) { + const ARP *arp_resp = response->find_pdu(); + if(arp_resp) + return arp_resp->sender_hw_addr(); + } + throw std::runtime_error("Could not resolve hardware address"); +} + bool Utils::gateway_from_ip(IPv4Address ip, IPv4Address &gw_addr) { typedef std::vector entries_type; entries_type entries;