Packets/80221Bundle: fixed typo in MIH message validation :-/
[senf.git] / senf / Packets / 80221Bundle / TLVParser.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Thorsten Horstmann <tho@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief TLVParser non-inline non-template implementation */
25
26 #include "TLVParser.hh"
27 //#include "TLVParser.ih"
28
29 // Custom includes
30 #include <senf/Utils/hexdump.hh>
31 #include <senf/Utils/Format.hh>
32
33 #define prefix_
34 //-/////////////////////////////////////////////////////////////////////////////////////////////////
35
36 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFSrcIdTLVParser );
37 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFDstIdTLVParser );
38 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHStatusTLVParser );
39 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHValidTimeIntervalTLVParser );
40
41 //-/////////////////////////////////////////////////////////////////////////////////////////////////
42 // MIHBaseTLVParser
43
44 prefix_ void senf::MIHBaseTLVParser::validateType(boost::uint8_t expectedType)
45     const
46 {
47     if (! check( 1 + senf::bytes(length_()) + length()) )
48         throw InvalidMIHPacketException("truncated TLV.") << " Type: " << unsigned(type());
49     if (type() != expectedType)
50         throw InvalidMIHPacketException("wrong TLV type. expected ") << unsigned(expectedType) << " got " << unsigned(type());
51 }
52
53 prefix_ void senf::MIHBaseTLVParser::validateTypeLength(boost::uint8_t expectedType, MIHTLVLengthParser::value_type expectedLength)
54     const
55 {
56     validateType( expectedType);
57     if (length() != expectedLength)
58         throw InvalidMIHPacketException("invalid length in TLV.") << " Type: " << unsigned(type());
59 }
60
61 //-/////////////////////////////////////////////////////////////////////////////////////////////////
62 // senf::MIHBaseListTLVParser
63
64 prefix_ void senf::MIHBaseListTLVParser::maxListSize(MIHTLVLengthParser::value_type maxl)
65     const
66 {
67     protect(), listSize_().capacity( maxl);
68     maxLength( maxl + senf::bytes(listSize_()));
69 }
70
71 //-/////////////////////////////////////////////////////////////////////////////////////////////////
72 // senf::MIHFIdTLVParser
73
74 prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
75     const
76 {
77     senf::format::IndentHelper indent;
78     os << indent << "type:   " << unsigned (type()) << std::endl
79        << indent << "length: " << unsigned (length()) << std::endl
80        << indent << "value:\n";
81     std::string src_mihfId (valueAsString());
82     hexdump(src_mihfId.begin(), src_mihfId.end(), os);
83 }
84
85 prefix_ void senf::MIHFIdTLVParser::finalize()
86 {
87     protect(), idLength_().finalize();
88     length_() << idLength() + senf::bytes(idLength_());
89     MIHBaseTLVParser::finalize();
90 }
91
92 prefix_ void senf::MIHFIdTLVParser::maxIdLength(boost::uint8_t maxl)
93     const
94 {
95     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
96     if (maxl > 253)
97         throw std::length_error("maximum length of a MIHF_ID is 253 octets");
98     protect(), idLength_().capacity( maxl);
99     maxLength( maxl + senf::bytes(idLength_()));
100 }
101
102 prefix_ senf::safe_data_iterator senf::MIHFIdTLVParser::resizeValueField(
103         MIHTLVLengthParser::value_type size)
104 {
105     MIHTLVLengthParser::value_type current_length ( idLength());
106     idLength_() << size;
107     length_() << size + idLength_().bytes();
108
109     safe_data_iterator si (data(), valueBegin());
110     if (current_length > size)
111         data().erase( si, boost::next(si, current_length-size));
112     else
113         data().insert( si, size-current_length, 0);
114     return si;
115 }
116
117 prefix_ void senf::MIHFIdTLVParser::value(std::string const & id)
118 {
119     size_type str_size (id.size());
120     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
121     if (str_size > 253)
122         throw std::length_error("maximum length of a MIHF_ID is 253 octets");
123     safe_data_iterator si = resizeValueField( str_size);
124     std::copy( id.begin(), id.end(), si);
125 }
126
127 prefix_ void senf::MIHFIdTLVParser::value(senf::MACAddress const & addr)
128 {
129     safe_data_iterator si = resizeValueField(6*2);
130     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
131 }
132
133 prefix_ void senf::MIHFIdTLVParser::value(senf::INet4Address const & addr)
134 {
135     safe_data_iterator si = resizeValueField(4*2);
136     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
137 }
138
139 prefix_ void senf::MIHFIdTLVParser::value(senf::INet6Address const & addr)
140 {
141     safe_data_iterator si = resizeValueField(16*2);
142     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
143 }
144
145 prefix_ void senf::MIHFIdTLVParser::value(senf::EUI64 const & addr)
146 {
147     safe_data_iterator si = resizeValueField(8*2);
148     std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
149 }
150
151 prefix_ void senf::MIHFIdTLVParser::value( MIHFId const & id)
152 {
153     boost::apply_visitor( ValueSetterVisitor(*this), id);
154 }
155
156 prefix_ senf::MIHFId senf::MIHFIdTLVParser::valueAs(MIHFId::Type type)
157     const
158 {
159     if (length() == 0) return MIHFId();
160     switch (type) {
161     case MIHFId::MulticastType:
162         return MIHFId();
163     case MIHFId::MACAddress:
164         return MIHFId( valueAsMACAddress());
165     case MIHFId::INet4Address:
166         return MIHFId( valueAsINet4Address());
167     case MIHFId::INet6Address:
168         return MIHFId( valueAsINet6Address());
169     case MIHFId::String:
170         return MIHFId( valueAsString());
171     case MIHFId::EUI64:
172         return MIHFId( valueAsEUI64());
173     }
174     return MIHFId();
175 }
176
177
178 //-/////////////////////////////////////////////////////////////////////////////////////////////////
179 // senf::MIHFSrcIdTLVParser
180
181 prefix_ void senf::MIHFSrcIdTLVParser::dump(std::ostream & os)
182     const
183 {
184     senf::format::IndentHelper indent;
185     os << indent << "source MIHF_Id TLV:\n";
186     MIHFIdTLVParser::dump(os);
187 }
188
189 prefix_ void senf::MIHFSrcIdTLVParser::validate()
190     const
191 {
192     validateType( typeId);
193 }
194
195
196 //-/////////////////////////////////////////////////////////////////////////////////////////////////
197 // senf::MIHFDstIdTLVParser
198
199 prefix_ void senf::MIHFDstIdTLVParser::dump(std::ostream & os)
200     const
201 {
202     senf::format::IndentHelper indent;
203     os << indent << "destination MIHF_Id TLV:\n";
204     MIHFIdTLVParser::dump(os);
205 }
206
207 prefix_ void senf::MIHFDstIdTLVParser::validate()
208     const
209 {
210     validateType( typeId);
211 }
212
213 //-/////////////////////////////////////////////////////////////////////////////////////////////////
214 // senf::MIHStatusTLVParser
215
216 prefix_ void senf::MIHStatusTLVParser::dump(std::ostream & os)
217     const
218 {
219     senf::format::IndentHelper indent;
220     os << indent << "Status TLV:" << std::endl;
221     indent.increase();
222     os << indent <<   "type:   " << unsigned( type()) << std::endl
223        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
224        << indent <<   "value:  " << unsigned( value());
225     switch (value()) {
226     case Success:
227         os << " (Success)" << std::endl;
228         return;
229     case UnspecifiedFailure:
230         os << " (Unspecified Failure)" << std::endl;
231         return;
232     case Rejected:
233         os << " (Rejected)" << std::endl;
234         return;
235     case AuthorizationFailure:
236         os << " (Authorization Failure)" << std::endl;
237         return;
238     case NetworkError:
239         os << " (Network Error)" << std::endl;
240         return;
241     }
242     os << " (???; invalid value!)" << std::endl;
243 }
244
245 prefix_ void senf::MIHStatusTLVParser::validate()
246     const
247 {
248     validateTypeLength( typeId, 1);
249     if (value() >= 4)
250         throw InvalidMIHPacketException("invalid value in MIHStatusTLV ") << unsigned( value());
251 }
252
253 //-/////////////////////////////////////////////////////////////////////////////////////////////////
254 // senf::MIHRegisterReqCodeTLVParser
255
256 prefix_ void senf::MIHRegisterReqCodeTLVParser::dump(std::ostream & os)
257     const
258 {
259     senf::format::IndentHelper indent;
260     os << indent << "Register Request Code TLV:" << std::endl;
261     indent.increase();
262     os << indent <<   "type:   " << unsigned( type()) << std::endl
263        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
264        << indent <<   "value:  " << unsigned( value());
265     switch (value()) {
266     case Registration:
267         os << " (Registration)" << std::endl;
268         return;
269     case ReRegistration:
270         os << " (Re-Registration)" << std::endl;
271         return;
272     }
273     os << " (???; invalid value!)" << std::endl;
274 }
275
276 prefix_ void senf::MIHRegisterReqCodeTLVParser::validate()
277     const
278 {
279     validateTypeLength( typeId, 1);
280     if (value() >= 2)
281         throw InvalidMIHPacketException("invalid value in MIHRegisterReqCodeTLV ") << unsigned( value());
282 }
283
284 //-/////////////////////////////////////////////////////////////////////////////////////////////////
285 // senf::MIHValidTimeIntervalTLVParser
286
287 prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os)
288     const
289 {
290     senf::format::IndentHelper indent;
291     os << indent << "Valid Time Interval TLV:" << std::endl;
292     indent.increase();
293     os << indent <<   "type:   " << unsigned( type()) << std::endl
294        << indent <<   "length: " << unsigned( length()) << " byte(s)" << std::endl
295        << indent <<   "value:  " << unsigned( value())
296        << ( value()==0 ? " (infinite)" : " seconds") << std::endl;
297 }
298
299 prefix_ void senf::MIHValidTimeIntervalTLVParser::validate()
300     const
301 {
302     validateTypeLength( typeId, 4);
303 }
304
305 //-/////////////////////////////////////////////////////////////////////////////////////////////////
306 // senf::MIHTLVLengthParser
307
308 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const
309 {
310     switch (bytes() ) {
311     case 1:
312         return length_field().value();
313     case 2:
314         return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
315     case 3:
316         return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
317     case 4:
318         return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
319     case 5:
320         return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
321     default:
322         throw( MIHTLVLengthException());
323     };
324 }
325
326 prefix_ void senf::MIHTLVLengthParser::value(value_type const & v)
327 {
328     switch (bytes() ) {
329     case 1:
330         if (v > 128) throw( MIHTLVLengthException());
331         length_field() = v;
332         return;
333     case 2:
334         if (v > UInt8Parser::max_value + 128) throw( MIHTLVLengthException());
335         parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
336         break;
337     case 3:
338         if (v > UInt16Parser::max_value + 128) throw( MIHTLVLengthException());
339         parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
340         break;;
341     case 4:
342         if (v > UInt24Parser::max_value + 128) throw( MIHTLVLengthException());
343         parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
344         break;
345     case 5:
346         parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
347         break;
348     default:
349         throw( MIHTLVLengthException());
350     };
351     underflow_flag() = (v <= 128);
352 }
353
354 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::capacity()
355     const
356 {
357     switch (bytes() ) {
358     case 1:
359         return 128;
360     case 2:
361         return UInt8Parser::max_value + 128;
362     case 3:
363         return UInt16Parser::max_value + 128;
364     case 4:
365         return UInt24Parser::max_value + 128;
366     case 5:
367         return UInt32Parser::max_value;
368     default:
369         throw( MIHTLVLengthException());
370     };
371 }
372
373 prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other)
374 {
375     value(other);
376     return *this;
377 }
378
379 prefix_ void senf::MIHTLVLengthParser::init() const
380 {
381     defaultInit();
382     extended_length_flag() = false;
383 }
384
385 prefix_ void senf::MIHTLVLengthParser::finalize()
386 {
387     value_type v = value();
388     size_type b = bytes();
389     if (v <= 128) {
390         if (b != 1) resize_(1);
391         return;
392     }
393     if (v <= UInt8Parser::max_value + 128) {
394         if (b != 2) resize_(2);
395         return;
396     }
397     if (v <= UInt16Parser::max_value + 128) {
398         if (b != 3) resize_(3);
399         return;
400     }
401     if (v <= UInt24Parser::max_value + 128 ) {
402         if (b != 4) resize_(4);
403         return;
404     }
405     if (b != 5) resize_(5);
406 }
407
408 prefix_ void senf::MIHTLVLengthParser::capacity(MIHTLVLengthParser::value_type v)
409 {
410     if (v <= 128)
411         return;
412     size_type b = bytes();
413     if (v <= UInt8Parser::max_value + 128) {
414         if (b < 2) resize_(2);
415         return;
416     }
417     if (v <= UInt16Parser::max_value + 128) {
418         if (b < 3) resize_(3);
419         return;
420     }
421     if (v <= UInt24Parser::max_value + 128) {
422         if (b < 4) resize_(4);
423         return;
424     }
425     if (b < 5) resize_(5);
426 }
427
428 prefix_ void senf::MIHTLVLengthParser::resize_(size_type size)
429 {
430     value_type v = value();
431     resize(bytes(), size);
432     if (size > 1) {
433         extended_length_flag() = true;
434         fixed_length_field() = size - 1;
435     } else {
436         extended_length_flag() = false;
437     }
438     value(v);
439 }
440
441
442 //-/////////////////////////////////////////////////////////////////////////////////////////////////
443 #undef prefix_
444
445 \f
446 // Local Variables:
447 // mode: c++
448 // fill-column: 100
449 // c-file-style: "senf"
450 // indent-tabs-mode: nil
451 // ispell-local-dictionary: "american"
452 // compile-command: "scons -u test"
453 // comment-column: 40
454 // End: