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

Removed the useless PDU::flag member. Added a PDU concatenation operator.

This commit is contained in:
Matias Fontanini
2012-10-07 18:51:06 -03:00
parent da60d99f98
commit 153bcecc35
24 changed files with 169 additions and 89 deletions

View File

@@ -84,12 +84,12 @@ private:
ttls[i] = i; ttls[i] = i;
} }
sender.send(&ip); sender.send(ip);
// Give him a little time // Give him a little time
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
} }
running = false; running = false;
sender.send(&ip); sender.send(ip);
} }
bool sniff_callback(PDU &pdu) { bool sniff_callback(PDU &pdu) {

View File

@@ -92,7 +92,8 @@ namespace Tins {
EAPOL, EAPOL,
RC4EAPOL, RC4EAPOL,
RSNEAPOL, RSNEAPOL,
DNS DNS,
LOOPBACK
}; };
/** \brief PDU constructor /** \brief PDU constructor
@@ -101,7 +102,7 @@ namespace Tins {
* \param flag The flag identifier for the subclass' PDU. * \param flag The flag identifier for the subclass' PDU.
* \param next_pdu The child PDU. Can be obviated. * \param next_pdu The child PDU. Can be obviated.
*/ */
PDU(uint32_t flag, PDU *next_pdu = 0); PDU(PDU *next_pdu = 0);
/** \brief PDU destructor. /** \brief PDU destructor.
* *
@@ -126,12 +127,6 @@ namespace Tins {
*/ */
uint32_t size() const; uint32_t size() const;
/**
* \brief Getter for this PDU's type flag identifier.
* \return The type flag identifier.
*/
uint32_t flag() const { return _flag; }
/** /**
* \brief Getter for the inner PDU. * \brief Getter for the inner PDU.
* \return The current inner PDU. Might be 0. * \return The current inner PDU. Might be 0.
@@ -153,10 +148,6 @@ namespace Tins {
*/ */
PDU *release_inner_pdu(); PDU *release_inner_pdu();
/** \brief Sets the flag identifier.
*/
void flag(uint32_t new_flag);
/** /**
* \brief Sets the child PDU. * \brief Sets the child PDU.
* *
@@ -310,20 +301,47 @@ namespace Tins {
* \param parent The PDU that's one level below this one on the stack. Might be 0. * \param parent The PDU that's one level below this one on the stack. Might be 0.
*/ */
virtual void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) = 0; virtual void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) = 0;
/**
* \brief Generic clone pdu method.
*/
template<class T>
T *do_clone() const {
T *new_pdu = new T(*static_cast<const T*>(this));
//new_pdu->copy_inner_pdu(*this);
return new_pdu;
}
private: private:
uint32_t _flag;
PDU *_inner_pdu; PDU *_inner_pdu;
}; };
/**
* \brief Concatenation operator.
*
* This operator concatenates several PDUs. A copy of the right
* operand is set at the end of the left one's inner PDU chain.
* This means that:
*
* IP some_ip = IP("127.0.0.1") / TCP(12, 13) / RawPDU("bleh");
*
* Works as expected, meaning the output PDU will look like the
* following:
*
* IP - TCP - RawPDU
*
* \param lop The left operand, which will be the one modified.
* \param rop The right operand, the one which will be appended
* to lop.
*/
template<typename T>
T &operator/= (T &lop, const PDU &rop) {
PDU *last = &lop;
while(last->inner_pdu())
last = last->inner_pdu();
last->inner_pdu(rop.clone());
return lop;
}
/**
* \brief Concatenation operator.
*
* \sa operator/=
*/
template<typename T>
T operator/ (T lop, const PDU &rop) {
lop /= rop;
return lop;
}
}; };
#endif // TINS_PDU_H #endif // TINS_PDU_H

View File

@@ -23,6 +23,7 @@
#define TINS_RAWPDU_H #define TINS_RAWPDU_H
#include <vector> #include <vector>
#include <string>
#include "pdu.h" #include "pdu.h"
namespace Tins { namespace Tins {
@@ -53,6 +54,13 @@ namespace Tins {
* \param size The size of the payload. * \param size The size of the payload.
*/ */
RawPDU(const uint8_t *pload, uint32_t size); RawPDU(const uint8_t *pload, uint32_t size);
/**
* \brief Creates an instance of RawPDU from an input string.
*
* \param data The content of the payload.
*/
RawPDU(const std::string &data);
/** /**
* \brief Setter for the payload field * \brief Setter for the payload field

View File

@@ -31,6 +31,7 @@
#include "pdu.h" #include "pdu.h"
#include "ethernetII.h" #include "ethernetII.h"
#include "radiotap.h" #include "radiotap.h"
#include "loopback.h"
namespace Tins { namespace Tins {
/** /**
@@ -118,11 +119,11 @@ namespace Tins {
struct LoopData { struct LoopData {
pcap_t *handle; pcap_t *handle;
Functor c_handler; Functor c_handler;
bool wired; int iface_type;
LoopData(pcap_t *_handle, const Functor _handler, LoopData(pcap_t *_handle, const Functor _handler,
bool is_wired) int if_type)
: handle(_handle), c_handler(_handler), wired(is_wired) { } : handle(_handle), c_handler(_handler), iface_type(if_type) { }
}; };
BaseSniffer(const BaseSniffer&); BaseSniffer(const BaseSniffer&);
@@ -139,7 +140,7 @@ namespace Tins {
pcap_t *handle; pcap_t *handle;
bpf_u_int32 mask; bpf_u_int32 mask;
bpf_program actual_filter; bpf_program actual_filter;
bool wired; int iface_type;
}; };
/** /**
@@ -184,7 +185,7 @@ namespace Tins {
template<class Functor> template<class Functor>
void Tins::BaseSniffer::sniff_loop(Functor function, uint32_t max_packets) { void Tins::BaseSniffer::sniff_loop(Functor function, uint32_t max_packets) {
LoopData<Functor> data(handle, function, wired); LoopData<Functor> data(handle, function, iface_type);
pcap_loop(handle, max_packets, &BaseSniffer::callback_handler<Functor>, (u_char*)&data); pcap_loop(handle, max_packets, &BaseSniffer::callback_handler<Functor>, (u_char*)&data);
} }
@@ -200,14 +201,13 @@ namespace Tins {
std::auto_ptr<PDU> pdu; std::auto_ptr<PDU> pdu;
LoopData<Functor> *data = reinterpret_cast<LoopData<Functor>*>(args); LoopData<Functor> *data = reinterpret_cast<LoopData<Functor>*>(args);
bool ret_val(false); bool ret_val(false);
/*if(data->wired) if(data->iface_type == DLT_EN10MB)
ret_val = data->c_handler(Tins::EthernetII((const uint8_t*)packet, header->caplen));
else
pdu.reset(new Tins::RadioTap((const uint8_t*)packet, header->caplen));*/
if(data->wired)
ret_val = call_functor<Tins::EthernetII>(data, packet, header->caplen); ret_val = call_functor<Tins::EthernetII>(data, packet, header->caplen);
else else if(data->iface_type == DLT_IEEE802_11_RADIO)
ret_val = call_functor<Tins::RadioTap>(data, packet, header->caplen); ret_val = call_functor<Tins::RadioTap>(data, packet, header->caplen);
else if(data->iface_type == DLT_NULL)
ret_val = call_functor<Tins::Loopback>(data, packet, header->caplen);
if(!ret_val) if(!ret_val)
pcap_breakloop(data->handle); pcap_breakloop(data->handle);
} }

View File

@@ -36,7 +36,6 @@ namespace Tins {
ARP::ARP(ipaddress_type target_ip, ipaddress_type sender_ip, ARP::ARP(ipaddress_type target_ip, ipaddress_type sender_ip,
const hwaddress_type &target_hw, const hwaddress_type &sender_hw) const hwaddress_type &target_hw, const hwaddress_type &sender_hw)
: PDU(0x0608)
{ {
memset(&_arp, 0, sizeof(arphdr)); memset(&_arp, 0, sizeof(arphdr));
hw_addr_format((uint16_t)Constants::ARP::ETHER); hw_addr_format((uint16_t)Constants::ARP::ETHER);
@@ -50,7 +49,6 @@ ARP::ARP(ipaddress_type target_ip, ipaddress_type sender_ip,
} }
ARP::ARP(const uint8_t *buffer, uint32_t total_sz) ARP::ARP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Endian::host_to_be<uint16_t>(Constants::Ethernet::ARP))
{ {
if(total_sz < sizeof(arphdr)) if(total_sz < sizeof(arphdr))
throw runtime_error("Not enough size for an ARP header in the buffer."); throw runtime_error("Not enough size for an ARP header in the buffer.");

View File

@@ -26,12 +26,12 @@
namespace Tins{ namespace Tins{
BootP::BootP() BootP::BootP()
: PDU(255), _vend(64) { : _vend(64) {
std::memset(&_bootp, 0, sizeof(bootphdr)); std::memset(&_bootp, 0, sizeof(bootphdr));
} }
BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size) BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size)
: PDU(255), _vend(vend_field_size) : _vend(vend_field_size)
{ {
if(total_sz < sizeof(bootphdr) + vend_field_size) if(total_sz < sizeof(bootphdr) + vend_field_size)
throw std::runtime_error("Not enough size for a BootP header in the buffer."); throw std::runtime_error("Not enough size for a BootP header in the buffer.");

View File

@@ -31,11 +31,11 @@ using std::list;
namespace Tins { namespace Tins {
DNS::DNS() : PDU(255), extra_size(0) { DNS::DNS() : extra_size(0) {
std::memset(&dns, 0, sizeof(dns)); std::memset(&dns, 0, sizeof(dns));
} }
DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : PDU(255), extra_size(0) { DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : extra_size(0) {
if(total_sz < sizeof(dnshdr)) if(total_sz < sizeof(dnshdr))
throw std::runtime_error("Not enough size for a DNS header in the buffer."); throw std::runtime_error("Not enough size for a DNS header in the buffer.");
std::memcpy(&dns, buffer, sizeof(dnshdr)); std::memcpy(&dns, buffer, sizeof(dnshdr));

View File

@@ -46,20 +46,19 @@ namespace Tins {
const Dot11::address_type Dot11::BROADCAST = "ff:ff:ff:ff:ff:ff"; const Dot11::address_type Dot11::BROADCAST = "ff:ff:ff:ff:ff:ff";
Dot11::Dot11(const address_type &dst_hw_addr, PDU* child) Dot11::Dot11(const address_type &dst_hw_addr, PDU* child)
: PDU(ETHERTYPE_IP, child), _options_size(0) : PDU(child), _options_size(0)
{ {
memset(&_header, 0, sizeof(ieee80211_header)); memset(&_header, 0, sizeof(ieee80211_header));
addr1(dst_hw_addr); addr1(dst_hw_addr);
} }
Dot11::Dot11(const ieee80211_header *header_ptr) Dot11::Dot11(const ieee80211_header *header_ptr)
: PDU(ETHERTYPE_IP)
{ {
} }
Dot11::Dot11(const uint8_t *buffer, uint32_t total_sz) Dot11::Dot11(const uint8_t *buffer, uint32_t total_sz)
: PDU(ETHERTYPE_IP), _options_size(0) : _options_size(0)
{ {
if(total_sz < sizeof(_header)) if(total_sz < sizeof(_header))
throw runtime_error("Not enough size for an Dot11 header in the buffer."); throw runtime_error("Not enough size for an Dot11 header in the buffer.");

View File

@@ -28,14 +28,16 @@
namespace Tins { namespace Tins {
EAPOL::EAPOL(uint8_t packet_type, EAPOLTYPE type) : PDU(0xff) { EAPOL::EAPOL(uint8_t packet_type, EAPOLTYPE type)
{
std::memset(&_header, 0, sizeof(_header)); std::memset(&_header, 0, sizeof(_header));
_header.version = 1; _header.version = 1;
_header.packet_type = packet_type; _header.packet_type = packet_type;
_header.type = (uint8_t)type; _header.type = (uint8_t)type;
} }
EAPOL::EAPOL(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) { EAPOL::EAPOL(const uint8_t *buffer, uint32_t total_sz)
{
if(total_sz < sizeof(_header)) if(total_sz < sizeof(_header))
throw std::runtime_error("Not enough size for an EAPOL header in the buffer."); throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
std::memcpy(&_header, buffer, sizeof(_header)); std::memcpy(&_header, buffer, sizeof(_header));

View File

@@ -40,7 +40,7 @@ const EthernetII::address_type EthernetII::BROADCAST("ff:ff:ff:ff:ff:ff");
EthernetII::EthernetII(const NetworkInterface& iface, EthernetII::EthernetII(const NetworkInterface& iface,
const address_type &dst_hw_addr, const address_type &src_hw_addr, const address_type &dst_hw_addr, const address_type &src_hw_addr,
PDU* child) PDU* child)
: PDU(ETHERTYPE_IP, child) : PDU(child)
{ {
memset(&_eth, 0, sizeof(ethhdr)); memset(&_eth, 0, sizeof(ethhdr));
dst_addr(dst_hw_addr); dst_addr(dst_hw_addr);
@@ -51,7 +51,6 @@ EthernetII::EthernetII(const NetworkInterface& iface,
} }
EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz)
: PDU(ETHERTYPE_IP)
{ {
if(total_sz < sizeof(ethhdr)) if(total_sz < sizeof(ethhdr))
throw std::runtime_error("Not enough size for an ethernetII header in the buffer."); throw std::runtime_error("Not enough size for an ethernetII header in the buffer.");

View File

@@ -32,7 +32,8 @@
uint16_t Tins::ICMP::global_id = 0, Tins::ICMP::global_seq = 0; uint16_t Tins::ICMP::global_id = 0, Tins::ICMP::global_seq = 0;
Tins::ICMP::ICMP(Flags flag) : PDU(IPPROTO_ICMP) { Tins::ICMP::ICMP(Flags flag)
{
std::memset(&_icmp, 0, sizeof(icmphdr)); std::memset(&_icmp, 0, sizeof(icmphdr));
switch(flag) { switch(flag) {
case ECHO_REPLY: case ECHO_REPLY:
@@ -48,7 +49,8 @@ Tins::ICMP::ICMP(Flags flag) : PDU(IPPROTO_ICMP) {
}; };
} }
Tins::ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_ICMP) { Tins::ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz)
{
if(total_sz < sizeof(icmphdr)) if(total_sz < sizeof(icmphdr))
throw std::runtime_error("Not enough size for an ICMP header in the buffer."); throw std::runtime_error("Not enough size for an ICMP header in the buffer.");
std::memcpy(&_icmp, buffer, sizeof(icmphdr)); std::memcpy(&_icmp, buffer, sizeof(icmphdr));

View File

@@ -38,7 +38,7 @@ const IEEE802_3::address_type IEEE802_3::BROADCAST("ff:ff:ff:ff:ff:ff");
IEEE802_3::IEEE802_3(const NetworkInterface& iface, IEEE802_3::IEEE802_3(const NetworkInterface& iface,
const address_type &dst_hw_addr, const address_type &src_hw_addr, const address_type &dst_hw_addr, const address_type &src_hw_addr,
PDU* child) PDU* child)
: PDU(ETHERTYPE_IP, child) : PDU(child)
{ {
memset(&_eth, 0, sizeof(ethhdr)); memset(&_eth, 0, sizeof(ethhdr));
this->dst_addr(dst_hw_addr); this->dst_addr(dst_hw_addr);
@@ -49,7 +49,6 @@ IEEE802_3::IEEE802_3(const NetworkInterface& iface,
} }
IEEE802_3::IEEE802_3(const uint8_t *buffer, uint32_t total_sz) IEEE802_3::IEEE802_3(const uint8_t *buffer, uint32_t total_sz)
: PDU(ETHERTYPE_IP)
{ {
if(total_sz < sizeof(ethhdr)) if(total_sz < sizeof(ethhdr))
throw std::runtime_error("Not enough size for an ethernetII header in the buffer."); throw std::runtime_error("Not enough size for an ethernetII header in the buffer.");

View File

@@ -43,7 +43,7 @@ namespace Tins {
const uint8_t IP::DEFAULT_TTL = 128; const uint8_t IP::DEFAULT_TTL = 128;
IP::IP(address_type ip_dst, address_type ip_src, PDU *child) IP::IP(address_type ip_dst, address_type ip_src, PDU *child)
: PDU(Constants::IP::PROTO_IP, child) : PDU(child)
{ {
init_ip_fields(); init_ip_fields();
this->dst_addr(ip_dst); this->dst_addr(ip_dst);
@@ -51,7 +51,6 @@ IP::IP(address_type ip_dst, address_type ip_src, PDU *child)
} }
IP::IP(const uint8_t *buffer, uint32_t total_sz) IP::IP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Constants::IP::PROTO_IP)
{ {
const char *msg = "Not enough size for an IP header in the buffer."; const char *msg = "Not enough size for an IP header in the buffer.";
if(total_sz < sizeof(iphdr)) if(total_sz < sizeof(iphdr))
@@ -329,7 +328,7 @@ bool IP::send(PacketSender& sender) {
link_addr.sin_family = AF_INET; link_addr.sin_family = AF_INET;
link_addr.sin_port = 0; link_addr.sin_port = 0;
link_addr.sin_addr.s_addr = _ip.daddr; link_addr.sin_addr.s_addr = _ip.daddr;
if(inner_pdu() && inner_pdu()->flag() == IPPROTO_ICMP) if(inner_pdu() && inner_pdu()->pdu_type() == PDU::ICMP)
type = PacketSender::ICMP_SOCKET; type = PacketSender::ICMP_SOCKET;
return sender.send_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type); return sender.send_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type);
@@ -341,7 +340,7 @@ PDU *IP::recv_response(PacketSender &sender) {
link_addr.sin_family = AF_INET; link_addr.sin_family = AF_INET;
link_addr.sin_port = 0; link_addr.sin_port = 0;
link_addr.sin_addr.s_addr = _ip.daddr; link_addr.sin_addr.s_addr = _ip.daddr;
if(inner_pdu() && inner_pdu()->flag() == IPPROTO_ICMP) if(inner_pdu() && inner_pdu()->pdu_type() == PDU::ICMP)
type = PacketSender::ICMP_SOCKET; type = PacketSender::ICMP_SOCKET;
return sender.recv_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type); return sender.recv_l3(*this, (struct sockaddr*)&link_addr, sizeof(link_addr), type);
@@ -352,15 +351,28 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare
assert(total_sz >= my_sz); assert(total_sz >= my_sz);
if(inner_pdu()) { if(inner_pdu()) {
uint32_t new_flag; uint32_t new_flag;
new_flag = inner_pdu()->flag(); switch(inner_pdu()->pdu_type()) {
if(new_flag == IPPROTO_IP) case PDU::IP:
new_flag = IPPROTO_IPIP; new_flag = IPPROTO_IPIP;
break;
this->protocol(new_flag); case PDU::TCP:
this->flag(new_flag); new_flag = IPPROTO_TCP;
break;
case PDU::UDP:
new_flag = IPPROTO_UDP;
break;
case PDU::ICMP:
new_flag = IPPROTO_ICMP;
break;
default:
// check for other protos
new_flag = 0xff;
};
protocol(new_flag);
//flag(new_flag);
} }
this->tot_len(total_sz); tot_len(total_sz);
this->head_len(my_sz / sizeof(uint32_t)); head_len(my_sz / sizeof(uint32_t));
memcpy(buffer, &_ip, sizeof(_ip)); memcpy(buffer, &_ip, sizeof(_ip));

View File

@@ -33,14 +33,18 @@ namespace Tins {
const uint8_t LLC::GLOBAL_DSAP_ADDR = 0xFF; const uint8_t LLC::GLOBAL_DSAP_ADDR = 0xFF;
const uint8_t LLC::NULL_ADDR = 0x00; const uint8_t LLC::NULL_ADDR = 0x00;
LLC::LLC(PDU *child) : PDU(0xff, child), _type(LLC::INFORMATION) { LLC::LLC(PDU *child)
: PDU(child), _type(LLC::INFORMATION)
{
memset(&_header, 0, sizeof(llchdr)); memset(&_header, 0, sizeof(llchdr));
control_field_length = 2; control_field_length = 2;
memset(&control_field, 0, sizeof(control_field)); memset(&control_field, 0, sizeof(control_field));
information_field_length = 0; information_field_length = 0;
} }
LLC::LLC(uint8_t dsap, uint8_t ssap, PDU *child) : PDU(0xff, child), _type(LLC::INFORMATION) { LLC::LLC(uint8_t dsap, uint8_t ssap, PDU *child)
: PDU(child), _type(LLC::INFORMATION)
{
_header.dsap = dsap; _header.dsap = dsap;
_header.ssap = ssap; _header.ssap = ssap;
control_field_length = 2; control_field_length = 2;
@@ -48,7 +52,7 @@ LLC::LLC(uint8_t dsap, uint8_t ssap, PDU *child) : PDU(0xff, child), _type(LLC::
information_field_length = 0; information_field_length = 0;
} }
LLC::LLC(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) { LLC::LLC(const uint8_t *buffer, uint32_t total_sz) {
// header + 1 info byte // header + 1 info byte
if(total_sz < sizeof(_header) + 1) if(total_sz < sizeof(_header) + 1)
throw std::runtime_error("Not enough size for a LLC header in the buffer."); throw std::runtime_error("Not enough size for a LLC header in the buffer.");

View File

@@ -26,17 +26,15 @@
namespace Tins { namespace Tins {
PDU::PDU(uint32_t flag, PDU *next_pdu) : _flag(flag), _inner_pdu(next_pdu) { PDU::PDU(PDU *next_pdu) : _inner_pdu(next_pdu) {
} }
PDU::PDU(const PDU &other) : _inner_pdu(0) { PDU::PDU(const PDU &other) : _inner_pdu(0) {
_flag = other.flag();
copy_inner_pdu(other); copy_inner_pdu(other);
} }
PDU &PDU::operator=(const PDU &other) { PDU &PDU::operator=(const PDU &other) {
_flag = other.flag();
copy_inner_pdu(other); copy_inner_pdu(other);
return *this; return *this;
} }
@@ -68,10 +66,6 @@ PDU *PDU::recv_response(PacketSender &) {
return false; return false;
} }
void PDU::flag(uint32_t new_flag) {
_flag = new_flag;
}
void PDU::inner_pdu(PDU *next_pdu) { void PDU::inner_pdu(PDU *next_pdu) {
delete _inner_pdu; delete _inner_pdu;
_inner_pdu = next_pdu; _inner_pdu = next_pdu;

View File

@@ -33,14 +33,13 @@
Tins::RadioTap::RadioTap(const NetworkInterface &iface, PDU *child) Tins::RadioTap::RadioTap(const NetworkInterface &iface, PDU *child)
: PDU(0xff, child), _iface(iface), _options_size(0) : PDU(child), _iface(iface), _options_size(0)
{ {
std::memset(&_radio, 0, sizeof(_radio)); std::memset(&_radio, 0, sizeof(_radio));
init(); init();
} }
Tins::RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) Tins::RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz)
: PDU(0xff)
{ {
static const std::string msg("Not enough size for an RadioTap header in the buffer."); static const std::string msg("Not enough size for an RadioTap header in the buffer.");
if(total_sz < sizeof(_radio)) if(total_sz < sizeof(_radio))

View File

@@ -26,11 +26,16 @@
namespace Tins { namespace Tins {
RawPDU::RawPDU(const uint8_t *pload, uint32_t size) RawPDU::RawPDU(const uint8_t *pload, uint32_t size)
: PDU(255), _payload(pload, pload + size) : _payload(pload, pload + size)
{ {
} }
RawPDU::RawPDU(const std::string &data)
: _payload(data.begin(), data.end()) {
}
uint32_t RawPDU::header_size() const { uint32_t RawPDU::header_size() const {
return _payload.size(); return _payload.size();
} }

View File

@@ -32,13 +32,15 @@
#include "eapol.h" #include "eapol.h"
Tins::SNAP::SNAP(PDU *child) : PDU(0xff, child) { Tins::SNAP::SNAP(PDU *child) : PDU(child)
{
std::memset(&_snap, 0, sizeof(_snap)); std::memset(&_snap, 0, sizeof(_snap));
_snap.dsap = _snap.ssap = 0xaa; _snap.dsap = _snap.ssap = 0xaa;
_snap.control = 3; _snap.control = 3;
} }
Tins::SNAP::SNAP(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) { Tins::SNAP::SNAP(const uint8_t *buffer, uint32_t total_sz)
{
if(total_sz < sizeof(_snap)) if(total_sz < sizeof(_snap))
throw std::runtime_error("Not enough size for a SNAP header in the buffer."); throw std::runtime_error("Not enough size for a SNAP header in the buffer.");
std::memcpy(&_snap, buffer, sizeof(_snap)); std::memcpy(&_snap, buffer, sizeof(_snap));

View File

@@ -44,7 +44,7 @@ void BaseSniffer::init(pcap_t *phandle, const std::string &filter,
handle = phandle; handle = phandle;
mask = if_mask; mask = if_mask;
wired = (pcap_datalink(handle) != DLT_IEEE802_11_RADIO); //better plx iface_type = pcap_datalink(handle);
actual_filter.bf_insns = 0; actual_filter.bf_insns = 0;
if(!filter.empty() && !set_filter(filter)) if(!filter.empty() && !set_filter(filter))
throw runtime_error("Invalid filter"); throw runtime_error("Invalid filter");
@@ -61,10 +61,12 @@ PDU *BaseSniffer::next_packet() {
const u_char *content = pcap_next(handle, &header); const u_char *content = pcap_next(handle, &header);
if(content) { if(content) {
try { try {
if(wired) if(iface_type == DLT_EN10MB)
ret = new EthernetII((const uint8_t*)content, header.caplen); ret = new EthernetII((const uint8_t*)content, header.caplen);
else else if(iface_type == DLT_IEEE802_11_RADIO)
ret = new RadioTap((const uint8_t*)content, header.caplen); ret = new RadioTap((const uint8_t*)content, header.caplen);
else if(iface_type == DLT_LOOP)
ret = new Tins::Loopback((const uint8_t*)content, header.caplen);
} }
catch(...) { catch(...) {
ret = 0; ret = 0;

View File

@@ -32,7 +32,7 @@ namespace Tins {
const uint16_t TCP::DEFAULT_WINDOW = 32678; const uint16_t TCP::DEFAULT_WINDOW = 32678;
TCP::TCP(uint16_t dport, uint16_t sport) TCP::TCP(uint16_t dport, uint16_t sport)
: PDU(Constants::IP::PROTO_TCP), _options_size(0), _total_options_size(0) : _options_size(0), _total_options_size(0)
{ {
std::memset(&_tcp, 0, sizeof(tcphdr)); std::memset(&_tcp, 0, sizeof(tcphdr));
this->dport(dport); this->dport(dport);
@@ -42,7 +42,6 @@ TCP::TCP(uint16_t dport, uint16_t sport)
} }
TCP::TCP(const uint8_t *buffer, uint32_t total_sz) TCP::TCP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Constants::IP::PROTO_TCP)
{ {
if(total_sz < sizeof(tcphdr)) if(total_sz < sizeof(tcphdr))
throw std::runtime_error("Not enough size for an TCP header in the buffer."); throw std::runtime_error("Not enough size for an TCP header in the buffer.");

View File

@@ -42,8 +42,8 @@ TCPStream::StreamInfo::StreamInfo(IPv4Address client,
TCPStream::TCPStream(IP *ip, TCP *tcp, uint64_t identifier) TCPStream::TCPStream(IP *ip, TCP *tcp, uint64_t identifier)
: client_seq(tcp->seq()), info(ip->src_addr(), ip->dst_addr(), : client_seq(tcp->seq()), server_seq(0), info(ip->src_addr(),
tcp->sport(), tcp->dport()), identifier(identifier), ip->dst_addr(), tcp->sport(), tcp->dport()), identifier(identifier),
syn_ack_sent(false), fin_sent(false) syn_ack_sent(false), fin_sent(false)
{ {

View File

@@ -29,7 +29,7 @@
#include "rawpdu.h" #include "rawpdu.h"
Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child) Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child)
: PDU(Constants::IP::PROTO_UDP, child) : PDU(child)
{ {
this->dport(dport); this->dport(dport);
this->sport(sport); this->sport(sport);
@@ -38,7 +38,6 @@ Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child)
} }
Tins::UDP::UDP(const uint8_t *buffer, uint32_t total_sz) Tins::UDP::UDP(const uint8_t *buffer, uint32_t total_sz)
: PDU(Constants::IP::PROTO_UDP)
{ {
if(total_sz < sizeof(udphdr)) if(total_sz < sizeof(udphdr))
throw std::runtime_error("Not enough size for an UDP header in the buffer."); throw std::runtime_error("Not enough size for an UDP header in the buffer.");

View File

@@ -151,6 +151,28 @@ src/network_interface.o: src/network_interface.cpp \
../include/ip_address.h: ../include/ip_address.h:
../include/utils.h: ../include/utils.h:
src/pdu.o: src/pdu.cpp ../include/ip.h ../include/pdu.h \
../include/small_uint.h ../include/endianness.h ../include/ip_address.h \
../include/pdu_option.h ../include/tcp.h ../include/rawpdu.h \
../include/pdu.h
../include/ip.h:
../include/pdu.h:
../include/small_uint.h:
../include/endianness.h:
../include/ip_address.h:
../include/pdu_option.h:
../include/tcp.h:
../include/rawpdu.h:
../include/pdu.h:
src/snap.o: src/snap.cpp ../include/snap.h ../include/pdu.h \ src/snap.o: src/snap.cpp ../include/snap.h ../include/pdu.h \
../include/endianness.h ../include/small_uint.h ../include/utils.h \ ../include/endianness.h ../include/small_uint.h ../include/utils.h \
../include/ip_address.h ../include/hw_address.h ../include/ip_address.h ../include/hw_address.h

View File

@@ -3,6 +3,9 @@
#include <string> #include <string>
#include <stdint.h> #include <stdint.h>
#include "ip.h" #include "ip.h"
#include "tcp.h"
#include "udp.h"
#include "icmp.h"
#include "ip_address.h" #include "ip_address.h"
#include "utils.h" #include "utils.h"
@@ -238,3 +241,17 @@ TEST_F(IPTest, Serialize) {
ASSERT_EQ(buffer.size(), sizeof(expected_packet)); ASSERT_EQ(buffer.size(), sizeof(expected_packet));
EXPECT_TRUE(std::equal(buffer.begin(), buffer.end(), expected_packet)); EXPECT_TRUE(std::equal(buffer.begin(), buffer.end(), expected_packet));
} }
TEST_F(IPTest, StackedProtocols) {
IP ip = IP() / TCP();
IP::serialization_type buffer = ip.serialize();
EXPECT_TRUE(IP(&buffer[0], buffer.size()).find_pdu<TCP>());
ip = IP() / UDP();
buffer = ip.serialize();
EXPECT_TRUE(IP(&buffer[0], buffer.size()).find_pdu<UDP>());
ip = IP() / ICMP();
buffer = ip.serialize();
EXPECT_TRUE(IP(&buffer[0], buffer.size()).find_pdu<ICMP>());
}