TLVParserBase.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "TLVParserBase.hh"
18 
19 // Custom includes
20 #include "Exceptions.hh"
21 
22 #define prefix_
23 //-/////////////////////////////////////////////////////////////////////////////////////////////////
24 
25 //-/////////////////////////////////////////////////////////////////////////////////////////////////
26 // MIHBaseTLVParser
27 
28 prefix_ void senf::MIHBaseTLVParser::validateType(boost::uint8_t expectedType)
29  const
30 {
31  if (! check( 1 + senf::bytes(length_()) + length()) )
32  throw InvalidMIHPacketException("truncated TLV.") << " Type: " << unsigned(type())
33  << ", size:" << 1 + senf::bytes(length_()) + length()
34  << ", available: " << std::distance(i(), data().end());
35  if (type() != expectedType)
36  throw InvalidMIHPacketException("wrong TLV type. expected ") << unsigned(expectedType) << " got " << unsigned(type());
37 }
38 
39 prefix_ void senf::MIHBaseTLVParser::validateTypeLength(boost::uint8_t expectedType, MIHLengthParser::value_type expectedLength)
40  const
41 {
42  validateType( expectedType);
43  if (length() != expectedLength)
44  throw InvalidMIHPacketException("invalid length in TLV.") << " Type: " << unsigned(type())
45  << ", expected length: " << expectedLength << " got " << length();
46 }
47 
48 //-/////////////////////////////////////////////////////////////////////////////////////////////////
49 // senf::MIHBaseListTLVParser
50 
52  const
53 {
54  protect(), listSize_().capacity( maxl);
55  maxLength( maxl + senf::bytes(listSize_()));
56 }
57 
58 //-/////////////////////////////////////////////////////////////////////////////////////////////////
59 // senf::MIHLengthParser
60 
62 {
63  switch (bytes() ) {
64  case 1:
65  return length_field().value();
66  case 2:
67  return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
68  case 3:
69  return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
70  case 4:
71  return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
72  case 5:
73  return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
74  default:
75  throw( MIHLengthException("cannot get length value: size of length field is greater than 5: ") << bytes());
76  }
77 }
78 
80 {
81  switch (bytes() ) {
82  case 1:
83  if (v > 128)
84  throw( MIHLengthException("cannot set length to ") << v << ": insufficient size of length field " << bytes());
85  length_field() = v;
86  return;
87  case 2:
88  if (v > UInt8Parser::max_value + 128)
89  throw( MIHLengthException("cannot set length to ") << v << ": insufficient size of length field " << bytes());
90  parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
91  break;
92  case 3:
93  if (v > UInt16Parser::max_value + 128)
94  throw( MIHLengthException("cannot set length to ") << v << ": insufficient size of length field " << bytes());
95  parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
96  break;;
97  case 4:
98  if (v > UInt24Parser::max_value + 128)
99  throw( MIHLengthException("cannot set length to ") << v << ": insufficient size of length field " << bytes());
100  parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
101  break;
102  case 5:
103  parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
104  break;
105  default:
106  throw( MIHLengthException("cannot set length to ") << v << ": size of length field is greater than 5: " << bytes());
107  };
108  underflow_flag() = (v <= 128);
109 }
110 
112  const
113 {
114  switch (bytes() ) {
115  case 1:
116  return 128;
117  case 2:
118  return UInt8Parser::max_value + 128;
119  case 3:
120  return UInt16Parser::max_value + 128;
121  case 4:
122  return UInt24Parser::max_value + 128;
123  case 5:
125  default:
126  throw( MIHLengthException("cannot get capacity: size of length field is greater than 5: ") << bytes());
127  };
128 }
129 
131 {
132  value(other);
133  return *this;
134 }
135 
137 {
138  defaultInit();
139  extended_length_flag() = false;
140 }
141 
143 {
144  value_type v = value();
145  size_type b = bytes();
146  if (v <= 128) {
147  if (b != 1) resize_(1);
148  return;
149  }
150  if (v <= UInt8Parser::max_value + 128) {
151  if (b != 2) resize_(2);
152  return;
153  }
154  if (v <= UInt16Parser::max_value + 128) {
155  if (b != 3) resize_(3);
156  return;
157  }
158  if (v <= UInt24Parser::max_value + 128 ) {
159  if (b != 4) resize_(4);
160  return;
161  }
162  if (b != 5) resize_(5);
163 }
164 
166 {
167  if (v <= 128)
168  return;
169  size_type b = bytes();
170  if (v <= UInt8Parser::max_value + 128) {
171  if (b < 2) resize_(2);
172  return;
173  }
174  if (v <= UInt16Parser::max_value + 128) {
175  if (b < 3) resize_(3);
176  return;
177  }
178  if (v <= UInt24Parser::max_value + 128) {
179  if (b < 4) resize_(4);
180  return;
181  }
182  if (b < 5) resize_(5);
183 }
184 
185 prefix_ void senf::MIHLengthParser::resize_(size_type size)
186 {
187  value_type v = value();
188  resize(bytes(), size);
189  if (size > 1) {
190  extended_length_flag() = true;
191  fixed_length_field() = size - 1;
192  } else {
193  extended_length_flag() = false;
194  }
195  value(v);
196 }
197 
198 
199 //-/////////////////////////////////////////////////////////////////////////////////////////////////
200 #undef prefix_
201 
202 
203 // Local Variables:
204 // mode: c++
205 // fill-column: 100
206 // c-file-style: "senf"
207 // indent-tabs-mode: nil
208 // ispell-local-dictionary: "american"
209 // compile-command: "scons -u test"
210 // comment-column: 40
211 // End:
static value_type const max_value
Definition: IntParser.hh:185
value_type value() const
void maxLength(MIHLengthParser::value_type maxl) const
set maximum value of TLV length field
void validateTypeLength(boost::uint8_t type, MIHLengthParser::value_type length) const
PacketParserBase::size_type bytes(Parser const &p)
Return raw size parsed by the given parser object.
UInt8Parser type() const
boost::uint32_t value_type
void defaultInit() const
Default implementation.
void maxListSize(MIHLengthParser::value_type maxl=MIHLengthParser::max_value) const
data_iterator i() const
Return beginning of data to parse.
MIHLengthParser ::value_type length() const
MIHLengthParser const & operator=(value_type other)
detail::packet::size_type size_type
Unsigned integral type.
bool check(size_type size) const
Check size of data container.
TLVParserBase public header.
void resize(size_type oldSize, size_type newSize)
Resize data container.
Definition: PacketParser.cc:26
PacketData & data() const
Access the packets raw data container.
static value_type const max_value
Definition: IntParser.hh:321
#define prefix_
static value_type const max_value
Definition: IntParser.hh:267
ParserProtector protect() const
value_type capacity() const
static value_type const max_value
Definition: IntParser.hh:102
void validateType(boost::uint8_t type) const
MIHLengthParser length_() const