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:
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
36
src/ip.cpp
36
src/ip.cpp
@@ -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));
|
||||||
|
|
||||||
|
|||||||
10
src/llc.cpp
10
src/llc.cpp
@@ -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.");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>());
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user