mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
145 lines
3.6 KiB
C++
145 lines
3.6 KiB
C++
/*
|
|
* Copyright (c) 2017, Matias Fontanini
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following disclaimer
|
|
* in the documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include <tins/pdu.h>
|
|
#include <tins/packet_sender.h>
|
|
|
|
using std::swap;
|
|
using std::vector;
|
|
|
|
namespace Tins {
|
|
|
|
PDU::metadata::metadata()
|
|
: header_size(0), current_pdu_type(PDU::UNKNOWN), next_pdu_type(PDU::UNKNOWN) {
|
|
|
|
}
|
|
|
|
PDU::metadata::metadata(uint32_t header_size, PDUType current_type, PDUType next_type)
|
|
: header_size(header_size), current_pdu_type(current_type), next_pdu_type(next_type) {
|
|
|
|
}
|
|
|
|
// PDU
|
|
|
|
PDU::PDU()
|
|
: inner_pdu_(), parent_pdu_() {
|
|
|
|
}
|
|
|
|
PDU::PDU(const PDU& other)
|
|
: inner_pdu_(), parent_pdu_() {
|
|
copy_inner_pdu(other);
|
|
}
|
|
|
|
PDU& PDU::operator=(const PDU& other) {
|
|
copy_inner_pdu(other);
|
|
return* this;
|
|
}
|
|
|
|
PDU::~PDU() {
|
|
delete inner_pdu_;
|
|
}
|
|
|
|
void PDU::copy_inner_pdu(const PDU& pdu) {
|
|
if (pdu.inner_pdu()) {
|
|
inner_pdu(pdu.inner_pdu()->clone());
|
|
}
|
|
}
|
|
|
|
void PDU::prepare_for_serialize() {
|
|
}
|
|
|
|
uint32_t PDU::size() const {
|
|
uint32_t sz = header_size() + trailer_size();
|
|
const PDU* ptr(inner_pdu_);
|
|
while (ptr) {
|
|
sz += ptr->header_size() + ptr->trailer_size();
|
|
ptr = ptr->inner_pdu();
|
|
}
|
|
return sz;
|
|
}
|
|
|
|
void PDU::send(PacketSender &, const NetworkInterface &) {
|
|
|
|
}
|
|
|
|
PDU* PDU::recv_response(PacketSender &, const NetworkInterface &) {
|
|
return 0;
|
|
}
|
|
|
|
bool PDU::matches_response(const uint8_t* /*ptr*/, uint32_t /*total_sz*/) const {
|
|
return false;
|
|
}
|
|
|
|
void PDU::inner_pdu(PDU* next_pdu) {
|
|
delete inner_pdu_;
|
|
inner_pdu_ = next_pdu;
|
|
if (inner_pdu_) {
|
|
inner_pdu_->parent_pdu(this);
|
|
}
|
|
}
|
|
|
|
void PDU::inner_pdu(const PDU& next_pdu) {
|
|
inner_pdu(next_pdu.clone());
|
|
}
|
|
|
|
PDU* PDU::release_inner_pdu() {
|
|
PDU* result = 0;
|
|
swap(result, inner_pdu_);
|
|
if (result) {
|
|
result->parent_pdu(0);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
PDU::serialization_type PDU::serialize() {
|
|
vector<uint8_t> buffer(size());
|
|
serialize(&buffer[0], static_cast<uint32_t>(buffer.size()));
|
|
return buffer;
|
|
}
|
|
|
|
void PDU::serialize(uint8_t* buffer, uint32_t total_sz) {
|
|
uint32_t sz = header_size() + trailer_size();
|
|
// Must not happen...
|
|
#ifdef TINS_DEBUG
|
|
assert(total_sz >= sz);
|
|
#endif
|
|
prepare_for_serialize();
|
|
if (inner_pdu_) {
|
|
inner_pdu_->serialize(buffer + header_size(), total_sz - sz);
|
|
}
|
|
write_serialization(buffer, total_sz);
|
|
}
|
|
|
|
void PDU::parent_pdu(PDU* parent) {
|
|
parent_pdu_ = parent;
|
|
}
|
|
|
|
} // Tins
|