From 1fbef641daddaa9f90fea2957eee0b4cadf0d63a Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Wed, 10 Apr 2013 18:44:00 -0300 Subject: [PATCH] TCP options now use PDUOption<>::length_field when it is != from data_size. --- include/pdu_option.h | 14 ++++++++------ src/tcp.cpp | 10 ++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/pdu_option.h b/include/pdu_option.h index 10a0679..5e43879 100644 --- a/include/pdu_option.h +++ b/include/pdu_option.h @@ -101,6 +101,8 @@ public: * when this option is serialized. Note that this can be different * to std::distance(start, end). * + * \sa length_field + * * \param opt The option type. * \param length The length of this option. * \param start The beginning of the option data. @@ -153,12 +155,12 @@ public: /** * \brief Retrieves the data length field. * - * This may be different to the actual size of the data. Note that - * in some protocols, such as TCP, the size of the length and the - * identifier fields is added to this field before serializing. - * Therefore, if on one of such protocols, an option's length_field - * returns X, then the actual length included in the serialized - * option will be X + C, where C is the size of those fields. + * This is what the size field will contain when this option is + * serialized. It can differ from the actual data size. + * + * This will be equal to data_size unless the constructor that takes + * both a data length and two iterators is used. + * * \sa data_size. */ diff --git a/src/tcp.cpp b/src/tcp.cpp index e92c262..05a806d 100644 --- a/src/tcp.cpp +++ b/src/tcp.cpp @@ -346,10 +346,12 @@ uint8_t *TCP::write_option(const option &opt, uint8_t *buffer) { } else { buffer[0] = opt.option(); - buffer[1] = opt.length_field() + (sizeof(uint8_t) << 1); - if(opt.data_size() != 0) - std::copy(opt.data_ptr(), opt.data_ptr() + opt.data_size(), buffer + 2); - return buffer + opt.data_size() + (sizeof(uint8_t) << 1); + buffer[1] = opt.length_field(); + // only add the identifier and size field sizes if the length + // field hasn't been spoofed. + if(opt.length_field() == opt.data_size()) + buffer[1] += (sizeof(uint8_t) << 1); + return std::copy(opt.data_ptr(), opt.data_ptr() + opt.data_size(), buffer + 2); } }