From 153bcecc35a8335b2635c0c0395986e3bce7b043 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Sun, 7 Oct 2012 18:51:06 -0300 Subject: [PATCH] Removed the useless PDU::flag member. Added a PDU concatenation operator. --- examples/traceroute.cpp | 4 +-- include/pdu.h | 64 ++++++++++++++++++++++++++--------------- include/rawpdu.h | 8 ++++++ include/sniffer.h | 22 +++++++------- src/arp.cpp | 2 -- src/bootp.cpp | 4 +-- src/dns.cpp | 4 +-- src/dot11.cpp | 5 ++-- src/eapol.cpp | 6 ++-- src/ethernetII.cpp | 3 +- src/icmp.cpp | 6 ++-- src/ieee802_3.cpp | 3 +- src/ip.cpp | 36 +++++++++++++++-------- src/llc.cpp | 10 +++++-- src/pdu.cpp | 8 +----- src/radiotap.cpp | 3 +- src/rawpdu.cpp | 7 ++++- src/snap.cpp | 6 ++-- src/sniffer.cpp | 8 ++++-- src/tcp.cpp | 3 +- src/tcp_stream.cpp | 4 +-- src/udp.cpp | 3 +- tests/depends.d | 22 ++++++++++++++ tests/src/ip.cpp | 17 +++++++++++ 24 files changed, 169 insertions(+), 89 deletions(-) diff --git a/examples/traceroute.cpp b/examples/traceroute.cpp index 6a5524b..226a412 100644 --- a/examples/traceroute.cpp +++ b/examples/traceroute.cpp @@ -84,12 +84,12 @@ private: ttls[i] = i; } - sender.send(&ip); + sender.send(ip); // Give him a little time std::this_thread::sleep_for(std::chrono::milliseconds(100)); } running = false; - sender.send(&ip); + sender.send(ip); } bool sniff_callback(PDU &pdu) { diff --git a/include/pdu.h b/include/pdu.h index 0093373..5ba1ae0 100644 --- a/include/pdu.h +++ b/include/pdu.h @@ -92,7 +92,8 @@ namespace Tins { EAPOL, RC4EAPOL, RSNEAPOL, - DNS + DNS, + LOOPBACK }; /** \brief PDU constructor @@ -101,7 +102,7 @@ namespace Tins { * \param flag The flag identifier for the subclass' PDU. * \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. * @@ -126,12 +127,6 @@ namespace Tins { */ 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. * \return The current inner PDU. Might be 0. @@ -153,10 +148,6 @@ namespace Tins { */ PDU *release_inner_pdu(); - /** \brief Sets the flag identifier. - */ - void flag(uint32_t new_flag); - /** * \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. */ virtual void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) = 0; - - /** - * \brief Generic clone pdu method. - */ - template - T *do_clone() const { - T *new_pdu = new T(*static_cast(this)); - //new_pdu->copy_inner_pdu(*this); - return new_pdu; - } private: - uint32_t _flag; 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 + 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 + T operator/ (T lop, const PDU &rop) { + lop /= rop; + return lop; + } }; #endif // TINS_PDU_H diff --git a/include/rawpdu.h b/include/rawpdu.h index bd033fc..8fe434e 100644 --- a/include/rawpdu.h +++ b/include/rawpdu.h @@ -23,6 +23,7 @@ #define TINS_RAWPDU_H #include +#include #include "pdu.h" namespace Tins { @@ -53,6 +54,13 @@ namespace Tins { * \param size The size of the payload. */ 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 diff --git a/include/sniffer.h b/include/sniffer.h index 38564c6..9cdae75 100644 --- a/include/sniffer.h +++ b/include/sniffer.h @@ -31,6 +31,7 @@ #include "pdu.h" #include "ethernetII.h" #include "radiotap.h" +#include "loopback.h" namespace Tins { /** @@ -118,11 +119,11 @@ namespace Tins { struct LoopData { pcap_t *handle; Functor c_handler; - bool wired; + int iface_type; LoopData(pcap_t *_handle, const Functor _handler, - bool is_wired) - : handle(_handle), c_handler(_handler), wired(is_wired) { } + int if_type) + : handle(_handle), c_handler(_handler), iface_type(if_type) { } }; BaseSniffer(const BaseSniffer&); @@ -139,7 +140,7 @@ namespace Tins { pcap_t *handle; bpf_u_int32 mask; bpf_program actual_filter; - bool wired; + int iface_type; }; /** @@ -184,7 +185,7 @@ namespace Tins { template void Tins::BaseSniffer::sniff_loop(Functor function, uint32_t max_packets) { - LoopData data(handle, function, wired); + LoopData data(handle, function, iface_type); pcap_loop(handle, max_packets, &BaseSniffer::callback_handler, (u_char*)&data); } @@ -200,14 +201,13 @@ namespace Tins { std::auto_ptr pdu; LoopData *data = reinterpret_cast*>(args); bool ret_val(false); - /*if(data->wired) - 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) + if(data->iface_type == DLT_EN10MB) ret_val = call_functor(data, packet, header->caplen); - else + else if(data->iface_type == DLT_IEEE802_11_RADIO) ret_val = call_functor(data, packet, header->caplen); + else if(data->iface_type == DLT_NULL) + ret_val = call_functor(data, packet, header->caplen); + if(!ret_val) pcap_breakloop(data->handle); } diff --git a/src/arp.cpp b/src/arp.cpp index ef39e79..8f69e7b 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -36,7 +36,6 @@ namespace Tins { ARP::ARP(ipaddress_type target_ip, ipaddress_type sender_ip, const hwaddress_type &target_hw, const hwaddress_type &sender_hw) -: PDU(0x0608) { memset(&_arp, 0, sizeof(arphdr)); 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) -: PDU(Endian::host_to_be(Constants::Ethernet::ARP)) { if(total_sz < sizeof(arphdr)) throw runtime_error("Not enough size for an ARP header in the buffer."); diff --git a/src/bootp.cpp b/src/bootp.cpp index 049f43d..d8acb5c 100644 --- a/src/bootp.cpp +++ b/src/bootp.cpp @@ -26,12 +26,12 @@ namespace Tins{ BootP::BootP() -: PDU(255), _vend(64) { +: _vend(64) { std::memset(&_bootp, 0, sizeof(bootphdr)); } 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) throw std::runtime_error("Not enough size for a BootP header in the buffer."); diff --git a/src/dns.cpp b/src/dns.cpp index 52d2f51..8dd0939 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -31,11 +31,11 @@ using std::list; namespace Tins { -DNS::DNS() : PDU(255), extra_size(0) { +DNS::DNS() : extra_size(0) { 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)) throw std::runtime_error("Not enough size for a DNS header in the buffer."); std::memcpy(&dns, buffer, sizeof(dnshdr)); diff --git a/src/dot11.cpp b/src/dot11.cpp index 253b876..51f0ec2 100644 --- a/src/dot11.cpp +++ b/src/dot11.cpp @@ -46,20 +46,19 @@ namespace Tins { const Dot11::address_type Dot11::BROADCAST = "ff:ff:ff:ff:ff:ff"; 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)); addr1(dst_hw_addr); } Dot11::Dot11(const ieee80211_header *header_ptr) -: PDU(ETHERTYPE_IP) { } Dot11::Dot11(const uint8_t *buffer, uint32_t total_sz) -: PDU(ETHERTYPE_IP), _options_size(0) +: _options_size(0) { if(total_sz < sizeof(_header)) throw runtime_error("Not enough size for an Dot11 header in the buffer."); diff --git a/src/eapol.cpp b/src/eapol.cpp index 60fbf4d..e467e34 100644 --- a/src/eapol.cpp +++ b/src/eapol.cpp @@ -28,14 +28,16 @@ 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)); _header.version = 1; _header.packet_type = packet_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)) throw std::runtime_error("Not enough size for an EAPOL header in the buffer."); std::memcpy(&_header, buffer, sizeof(_header)); diff --git a/src/ethernetII.cpp b/src/ethernetII.cpp index 111259f..8ef0b34 100644 --- a/src/ethernetII.cpp +++ b/src/ethernetII.cpp @@ -40,7 +40,7 @@ const EthernetII::address_type EthernetII::BROADCAST("ff:ff:ff:ff:ff:ff"); EthernetII::EthernetII(const NetworkInterface& iface, const address_type &dst_hw_addr, const address_type &src_hw_addr, PDU* child) -: PDU(ETHERTYPE_IP, child) +: PDU(child) { memset(&_eth, 0, sizeof(ethhdr)); dst_addr(dst_hw_addr); @@ -51,7 +51,6 @@ EthernetII::EthernetII(const NetworkInterface& iface, } EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) -: PDU(ETHERTYPE_IP) { if(total_sz < sizeof(ethhdr)) throw std::runtime_error("Not enough size for an ethernetII header in the buffer."); diff --git a/src/icmp.cpp b/src/icmp.cpp index 1234685..041dfe5 100644 --- a/src/icmp.cpp +++ b/src/icmp.cpp @@ -32,7 +32,8 @@ 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)); switch(flag) { 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)) throw std::runtime_error("Not enough size for an ICMP header in the buffer."); std::memcpy(&_icmp, buffer, sizeof(icmphdr)); diff --git a/src/ieee802_3.cpp b/src/ieee802_3.cpp index 19ec6d0..46e5037 100644 --- a/src/ieee802_3.cpp +++ b/src/ieee802_3.cpp @@ -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, const address_type &dst_hw_addr, const address_type &src_hw_addr, PDU* child) -: PDU(ETHERTYPE_IP, child) +: PDU(child) { memset(&_eth, 0, sizeof(ethhdr)); 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) -: PDU(ETHERTYPE_IP) { if(total_sz < sizeof(ethhdr)) throw std::runtime_error("Not enough size for an ethernetII header in the buffer."); diff --git a/src/ip.cpp b/src/ip.cpp index 1f98fe3..70e7002 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -43,7 +43,7 @@ namespace Tins { const uint8_t IP::DEFAULT_TTL = 128; IP::IP(address_type ip_dst, address_type ip_src, PDU *child) -: PDU(Constants::IP::PROTO_IP, child) +: PDU(child) { init_ip_fields(); 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) -: PDU(Constants::IP::PROTO_IP) { const char *msg = "Not enough size for an IP header in the buffer."; if(total_sz < sizeof(iphdr)) @@ -329,7 +328,7 @@ bool IP::send(PacketSender& sender) { link_addr.sin_family = AF_INET; link_addr.sin_port = 0; 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; 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_port = 0; 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; 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); if(inner_pdu()) { uint32_t new_flag; - new_flag = inner_pdu()->flag(); - if(new_flag == IPPROTO_IP) - new_flag = IPPROTO_IPIP; - - this->protocol(new_flag); - this->flag(new_flag); + switch(inner_pdu()->pdu_type()) { + case PDU::IP: + new_flag = IPPROTO_IPIP; + break; + case PDU::TCP: + 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); - this->head_len(my_sz / sizeof(uint32_t)); + tot_len(total_sz); + head_len(my_sz / sizeof(uint32_t)); memcpy(buffer, &_ip, sizeof(_ip)); diff --git a/src/llc.cpp b/src/llc.cpp index fa4e943..ec36338 100644 --- a/src/llc.cpp +++ b/src/llc.cpp @@ -33,14 +33,18 @@ namespace Tins { const uint8_t LLC::GLOBAL_DSAP_ADDR = 0xFF; 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)); control_field_length = 2; memset(&control_field, 0, sizeof(control_field)); 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.ssap = ssap; 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; } -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 if(total_sz < sizeof(_header) + 1) throw std::runtime_error("Not enough size for a LLC header in the buffer."); diff --git a/src/pdu.cpp b/src/pdu.cpp index e834f56..a358ef4 100644 --- a/src/pdu.cpp +++ b/src/pdu.cpp @@ -26,17 +26,15 @@ 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) { - _flag = other.flag(); copy_inner_pdu(other); } PDU &PDU::operator=(const PDU &other) { - _flag = other.flag(); copy_inner_pdu(other); return *this; } @@ -68,10 +66,6 @@ PDU *PDU::recv_response(PacketSender &) { return false; } -void PDU::flag(uint32_t new_flag) { - _flag = new_flag; -} - void PDU::inner_pdu(PDU *next_pdu) { delete _inner_pdu; _inner_pdu = next_pdu; diff --git a/src/radiotap.cpp b/src/radiotap.cpp index 98e86c2..b0e241e 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -33,14 +33,13 @@ 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)); init(); } 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."); if(total_sz < sizeof(_radio)) diff --git a/src/rawpdu.cpp b/src/rawpdu.cpp index 30b6fa4..08276c6 100644 --- a/src/rawpdu.cpp +++ b/src/rawpdu.cpp @@ -26,11 +26,16 @@ namespace Tins { 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 { return _payload.size(); } diff --git a/src/snap.cpp b/src/snap.cpp index 786441d..59f616f 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -32,13 +32,15 @@ #include "eapol.h" -Tins::SNAP::SNAP(PDU *child) : PDU(0xff, child) { +Tins::SNAP::SNAP(PDU *child) : PDU(child) +{ std::memset(&_snap, 0, sizeof(_snap)); _snap.dsap = _snap.ssap = 0xaa; _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)) throw std::runtime_error("Not enough size for a SNAP header in the buffer."); std::memcpy(&_snap, buffer, sizeof(_snap)); diff --git a/src/sniffer.cpp b/src/sniffer.cpp index bcf16ec..b90b16e 100644 --- a/src/sniffer.cpp +++ b/src/sniffer.cpp @@ -44,7 +44,7 @@ void BaseSniffer::init(pcap_t *phandle, const std::string &filter, handle = phandle; mask = if_mask; - wired = (pcap_datalink(handle) != DLT_IEEE802_11_RADIO); //better plx + iface_type = pcap_datalink(handle); actual_filter.bf_insns = 0; if(!filter.empty() && !set_filter(filter)) throw runtime_error("Invalid filter"); @@ -61,10 +61,12 @@ PDU *BaseSniffer::next_packet() { const u_char *content = pcap_next(handle, &header); if(content) { try { - if(wired) + if(iface_type == DLT_EN10MB) 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); + else if(iface_type == DLT_LOOP) + ret = new Tins::Loopback((const uint8_t*)content, header.caplen); } catch(...) { ret = 0; diff --git a/src/tcp.cpp b/src/tcp.cpp index 9f03455..9c6e99c 100644 --- a/src/tcp.cpp +++ b/src/tcp.cpp @@ -32,7 +32,7 @@ namespace Tins { const uint16_t TCP::DEFAULT_WINDOW = 32678; 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)); 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) -: PDU(Constants::IP::PROTO_TCP) { if(total_sz < sizeof(tcphdr)) throw std::runtime_error("Not enough size for an TCP header in the buffer."); diff --git a/src/tcp_stream.cpp b/src/tcp_stream.cpp index b38b2d0..cdb8fda 100644 --- a/src/tcp_stream.cpp +++ b/src/tcp_stream.cpp @@ -42,8 +42,8 @@ TCPStream::StreamInfo::StreamInfo(IPv4Address client, TCPStream::TCPStream(IP *ip, TCP *tcp, uint64_t identifier) -: client_seq(tcp->seq()), info(ip->src_addr(), ip->dst_addr(), - tcp->sport(), tcp->dport()), identifier(identifier), +: client_seq(tcp->seq()), server_seq(0), info(ip->src_addr(), + ip->dst_addr(), tcp->sport(), tcp->dport()), identifier(identifier), syn_ack_sent(false), fin_sent(false) { diff --git a/src/udp.cpp b/src/udp.cpp index f245eb5..1394e71 100644 --- a/src/udp.cpp +++ b/src/udp.cpp @@ -29,7 +29,7 @@ #include "rawpdu.h" Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child) -: PDU(Constants::IP::PROTO_UDP, child) +: PDU(child) { this->dport(dport); 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) -: PDU(Constants::IP::PROTO_UDP) { if(total_sz < sizeof(udphdr)) throw std::runtime_error("Not enough size for an UDP header in the buffer."); diff --git a/tests/depends.d b/tests/depends.d index e6d9a50..9b12a09 100644 --- a/tests/depends.d +++ b/tests/depends.d @@ -151,6 +151,28 @@ src/network_interface.o: src/network_interface.cpp \ ../include/ip_address.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 \ ../include/endianness.h ../include/small_uint.h ../include/utils.h \ ../include/ip_address.h ../include/hw_address.h diff --git a/tests/src/ip.cpp b/tests/src/ip.cpp index 1769ee3..c7eb7c4 100644 --- a/tests/src/ip.cpp +++ b/tests/src/ip.cpp @@ -3,6 +3,9 @@ #include #include #include "ip.h" +#include "tcp.h" +#include "udp.h" +#include "icmp.h" #include "ip_address.h" #include "utils.h" @@ -238,3 +241,17 @@ TEST_F(IPTest, Serialize) { ASSERT_EQ(buffer.size(), sizeof(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()); + + ip = IP() / UDP(); + buffer = ip.serialize(); + EXPECT_TRUE(IP(&buffer[0], buffer.size()).find_pdu()); + + ip = IP() / ICMP(); + buffer = ip.serialize(); + EXPECT_TRUE(IP(&buffer[0], buffer.size()).find_pdu()); +}