mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added PDU::rfind_pdu.
This commit is contained in:
@@ -30,12 +30,27 @@
|
||||
#ifndef TINS_CXXSTD_H
|
||||
#define TINS_CXXSTD_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
#define TINS_CXXSTD_GCC_FIX 1
|
||||
#else
|
||||
#define TINS_CXXSTD_GCC_FIX 0
|
||||
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
||||
|
||||
namespace Tins{
|
||||
namespace Internals {
|
||||
template<typename T>
|
||||
struct smart_ptr {
|
||||
#if TINS_IS_CXX11
|
||||
typedef std::unique_ptr<T> type;
|
||||
#else
|
||||
typedef std::auto_ptr<T> type;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#define TINS_IS_CXX11 (__cplusplus > 199711L || TINS_CXXSTD_GCC_FIX == 1)
|
||||
|
||||
#endif // TINS_CXXSTD_H
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Exception thrown when an option is not found.
|
||||
* \brief Exception thrown when a malformed packet is parsed.
|
||||
*/
|
||||
class malformed_packet : public std::runtime_error {
|
||||
public:
|
||||
@@ -56,7 +56,20 @@ public:
|
||||
: std::runtime_error(std::string()) { }
|
||||
|
||||
const char* what() const throw() {
|
||||
return "Option not found";
|
||||
return "Malformed packet";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Exception thrown when a PDU is not found when using PDU::rfind_pdu.
|
||||
*/
|
||||
class pdu_not_found : public std::runtime_error {
|
||||
public:
|
||||
pdu_not_found()
|
||||
: std::runtime_error(std::string()) { }
|
||||
|
||||
const char* what() const throw() {
|
||||
return "PDU not found";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <vector>
|
||||
#include "macros.h"
|
||||
#include "cxxstd.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
/** \brief The Tins namespace.
|
||||
*/
|
||||
@@ -220,14 +221,14 @@ namespace Tins {
|
||||
serialization_type serialize();
|
||||
|
||||
/**
|
||||
* \brief Find and returns the first PDU that matches the given flag.
|
||||
* \brief Finds and returns the first PDU that matches the given flag.
|
||||
*
|
||||
* This method searches for the first PDU which has the same type flag as
|
||||
* the given one. If the first PDU matches that flag, it is returned.
|
||||
* If no PDU matches, 0 is returned.
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<class T>
|
||||
template<typename T>
|
||||
T *find_pdu(PDUType type = T::pdu_flag) {
|
||||
PDU *pdu = this;
|
||||
while(pdu) {
|
||||
@@ -239,15 +240,42 @@ namespace Tins {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Find and returns the first PDU that matches the given flag.
|
||||
* \brief Finds and returns the first PDU that matches the given flag.
|
||||
*
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<class T>
|
||||
template<typename T>
|
||||
const T *find_pdu(PDUType type = T::pdu_flag) const {
|
||||
return const_cast<PDU*>(this)->find_pdu<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Finds and returns the first PDU that matches the given flag.
|
||||
*
|
||||
* If the PDU is not found, a pdu_not_found exception is thrown.
|
||||
*
|
||||
* \sa PDU::find_pdu
|
||||
*
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<typename T>
|
||||
T &rfind_pdu(PDUType type = T::pdu_flag) {
|
||||
T *ptr = find_pdu<T>(type);
|
||||
if(!ptr)
|
||||
throw pdu_not_found();
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Finds and returns the first PDU that matches the given flag.
|
||||
*
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<typename T>
|
||||
const T &rfind_pdu(PDUType type = T::pdu_flag) const {
|
||||
return const_cast<PDU*>(this)->rfind_pdu<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clones this packet.
|
||||
*
|
||||
|
||||
@@ -272,7 +272,7 @@ namespace Tins {
|
||||
bool ret_val(false);
|
||||
LoopData<Functor> *data = reinterpret_cast<LoopData<Functor>*>(args);
|
||||
try {
|
||||
std::auto_ptr<PDU> pdu;
|
||||
Internals::smart_ptr<PDU>::type pdu;
|
||||
if(data->iface_type == DLT_EN10MB)
|
||||
ret_val = call_functor<Tins::EthernetII>(data, packet, header);
|
||||
else if(data->iface_type == DLT_IEEE802_11_RADIO)
|
||||
|
||||
@@ -54,7 +54,7 @@ DNSResourceRecord::DNSResourceRecord(DNSRRImpl *impl,
|
||||
DNSResourceRecord::DNSResourceRecord(const uint8_t *buffer, uint32_t size)
|
||||
{
|
||||
const uint8_t *buffer_end = buffer + size;
|
||||
std::auto_ptr<DNSRRImpl> tmp_impl;
|
||||
Internals::smart_ptr<DNSRRImpl>::type tmp_impl;
|
||||
if((*buffer & 0xc0)) {
|
||||
uint16_t offset(*reinterpret_cast<const uint16_t*>(buffer));
|
||||
offset = Endian::be_to_host(offset) & 0x3fff;
|
||||
|
||||
@@ -117,11 +117,7 @@ bool resolve_hwaddr(const NetworkInterface &iface, IPv4Address ip,
|
||||
IPv4Address my_ip;
|
||||
NetworkInterface::Info info(iface.addresses());
|
||||
EthernetII packet = ARP::make_arp_request(iface, ip, info.ip_addr, info.hw_addr);
|
||||
#if TINS_IS_CXX11
|
||||
std::unique_ptr<PDU> response(sender.send_recv(packet));
|
||||
#else
|
||||
std::auto_ptr<PDU> response(sender.send_recv(packet));
|
||||
#endif
|
||||
Internals::smart_ptr<PDU>::type response(sender.send_recv(packet));
|
||||
if(response.get()) {
|
||||
ARP *arp_resp = response->find_pdu<ARP>();
|
||||
if(arp_resp)
|
||||
@@ -137,12 +133,7 @@ HWAddress<6> resolve_hwaddr(const NetworkInterface &iface, IPv4Address ip, Packe
|
||||
IPv4Address my_ip;
|
||||
NetworkInterface::Info info(iface.addresses());
|
||||
EthernetII packet = ARP::make_arp_request(iface, ip, info.ip_addr, info.hw_addr);
|
||||
#if TINS_IS_CXX11
|
||||
std::unique_ptr<PDU>
|
||||
#else
|
||||
std::auto_ptr<PDU>
|
||||
#endif
|
||||
response(sender.send_recv(packet));
|
||||
Internals::smart_ptr<PDU>::type response(sender.send_recv(packet));
|
||||
if(response.get()) {
|
||||
const ARP *arp_resp = response->find_pdu<ARP>();
|
||||
if(arp_resp)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
#include "dot11.h"
|
||||
#include "cxxstd.h"
|
||||
#include "tests/dot11.h"
|
||||
|
||||
|
||||
@@ -61,12 +62,12 @@ TEST_F(Dot11DataTest, SeqNum) {
|
||||
|
||||
TEST_F(Dot11DataTest, ClonePDU) {
|
||||
Dot11Data dot1(expected_packet, sizeof(expected_packet));
|
||||
std::auto_ptr<Dot11Data> dot2(dot1.clone());
|
||||
Internals::smart_ptr<Dot11Data>::type dot2(dot1.clone());
|
||||
test_equals(dot1, *dot2);
|
||||
}
|
||||
|
||||
TEST_F(Dot11DataTest, FromBytes) {
|
||||
std::auto_ptr<PDU> dot11(Dot11::from_bytes(expected_packet, sizeof(expected_packet)));
|
||||
Internals::smart_ptr<PDU>::type dot11(Dot11::from_bytes(expected_packet, sizeof(expected_packet)));
|
||||
ASSERT_TRUE(dot11.get());
|
||||
const Dot11Data *inner = dot11->find_pdu<Dot11Data>();
|
||||
ASSERT_TRUE(inner);
|
||||
@@ -94,7 +95,7 @@ TEST_F(Dot11DataTest, PCAPLoad1) {
|
||||
EXPECT_EQ(dot1.from_ds(), 1);
|
||||
EXPECT_EQ(dot1.frag_num(), 0);
|
||||
EXPECT_EQ(dot1.seq_num(), 1945);
|
||||
std::auto_ptr<Dot11Data> dot2(dot1.clone());
|
||||
Internals::smart_ptr<Dot11Data>::type dot2(dot1.clone());
|
||||
test_equals(dot1, *dot2);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdint.h>
|
||||
#include "ip.h"
|
||||
#include "tcp.h"
|
||||
#include "udp.h"
|
||||
#include "rawpdu.h"
|
||||
#include "pdu.h"
|
||||
#include "packet.h"
|
||||
@@ -15,6 +16,18 @@ class PDUTest : public testing::Test {
|
||||
public:
|
||||
};
|
||||
|
||||
TEST_F(PDUTest, FindPDU) {
|
||||
IP ip = IP("192.168.0.1") / TCP(22, 52) / RawPDU("Test");
|
||||
EXPECT_TRUE(ip.find_pdu<TCP>());
|
||||
EXPECT_TRUE(ip.find_pdu<RawPDU>());
|
||||
EXPECT_FALSE(ip.find_pdu<UDP>());
|
||||
TCP &t1 = ip.rfind_pdu<TCP>();
|
||||
const TCP &t2 = ip.rfind_pdu<TCP>();
|
||||
(void)t1;
|
||||
(void)t2;
|
||||
EXPECT_THROW(ip.rfind_pdu<UDP>(), pdu_not_found);
|
||||
}
|
||||
|
||||
TEST_F(PDUTest, OperatorConcat) {
|
||||
std::string raw_payload = "Test";
|
||||
IP ip = IP("192.168.0.1") / TCP(22, 52) / RawPDU(raw_payload);
|
||||
|
||||
Reference in New Issue
Block a user