4d637d0ecc71a139598f30d5150e94e34063fc24
[senf.git] / senf / Packets / 80221Bundle / TLVParser.test.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 unit tests */
25
26 //#include "TLVParser.test.hh"
27 //#include "TLVParser.test.ih"
28
29 // Custom includes
30 #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
31 #include "TLVParser.hh"
32 #include "Exceptions.hh"
33
34 #include <senf/Utils/auto_unit_test.hh>
35 #include <boost/test/test_tools.hpp>
36
37 #define prefix_
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
39
40 using namespace senf;
41
42 namespace {
43     struct VoidPacket : public PacketTypeBase
44     {};
45 }
46
47 #define CHECK_TLVParser(tlvParser, ptype, plength)                          \
48 {                                                                           \
49     BOOST_CHECK_EQUAL( tlvParser.type(),         ptype   );                 \
50     BOOST_CHECK_EQUAL( tlvParser.length(),       plength );                 \
51     BOOST_CHECK_EQUAL( tlvParser.value().size(), int(plength) );            \
52     senf::PacketData::iterator dataIterator (tlvParser.value().begin());    \
53     for (unsigned i=0; i<plength; i++) {                                    \
54         BOOST_CHECK_EQUAL( *dataIterator, i );                              \
55         dataIterator++;                                                     \
56     }                                                                       \
57 }
58
59
60 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_simple_length)
61 {
62     PacketInterpreterBase::byte data[] = {
63         0x01, // type
64         0x0A, // first bit not set, length=10
65         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
66     };
67     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(data));
68     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
69     CHECK_TLVParser( tlvParser, 0x01, 0x0Au );
70 }
71
72
73 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_extended_length)
74 {
75     PacketInterpreterBase::byte data[] = {
76         0x01, // type
77         0x81, // first and last bit set => one byte length following
78         0x0A, // length (10 = 138 bytes value follows)
79         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
80         0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
81         0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
82         0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
83         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
84         0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
85         0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
86         0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
87         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
88         0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
89         0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
90         0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
91         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81,
92         0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89
93     };
94     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(data));
95     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
96     CHECK_TLVParser( tlvParser, 0x01, 0x8au );
97 }
98
99
100 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_simple_length)
101 {
102     PacketInterpreterBase::byte value[] = {
103            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
104     };
105     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(
106             senf::PacketInterpreterBase::size_type(2u)));
107     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
108     tlvParser.type() = 42u;
109     tlvParser.value( value);
110     tlvParser.finalize();
111
112     CHECK_TLVParser( tlvParser, 42u, 0x0Au );
113
114     PacketInterpreterBase::byte data[] = {
115         0x2a, // type
116         0x0A, // first bit not set, length=10
117         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // value
118     };
119     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
120             p->data().begin(), p->data().end() );
121 }
122
123
124 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_extended_length)
125 {
126     PacketInterpreterBase::byte value[255];
127     for (unsigned i=0; i<sizeof(value); i++)
128         value[i] = i;
129     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(
130             senf::PacketInterpreterBase::size_type(2u)));
131     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
132     tlvParser.maxLength( MIHTLVLengthParser::max_value);
133     tlvParser.type() = 42u;
134     tlvParser.value( value);
135     tlvParser.finalize();
136
137     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
138
139     PacketInterpreterBase::byte data[] = {
140         0x2a, // type
141         0x81, // first and last bit set => one byte length following
142         0x7f, // length (127 = 255 bytes value)
143         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // first bytes of value
144     };
145     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
146             p->data().begin(), boost::next( p->data().begin(), sizeof(data)) );
147 }
148
149
150 SENF_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid)
151 {
152     PacketInterpreterBase::ptr p (PacketInterpreter<VoidPacket>::create(
153             senf::PacketInterpreterBase::size_type(2u)));
154     MIHGenericTLVParser tlvParser( p->data().begin(), &p->data());
155     tlvParser.type() = 42u;
156     tlvParser.finalize();
157
158     PacketInterpreterBase::byte value[255];
159     for (unsigned i=0; i<sizeof(value); i++)
160         value[i] = i;
161
162     BOOST_CHECK_THROW( tlvParser.value( value), MIHTLVLengthException);
163     tlvParser.maxLength( sizeof(value));
164     tlvParser.value( value);
165     tlvParser.finalize();
166     CHECK_TLVParser( tlvParser, 42u, sizeof(value) );
167 }
168
169
170 namespace {
171
172     struct TestMacAddressTLVPacketParser : public MIHBaseTLVParser
173     {
174     #   include SENF_PARSER()
175         SENF_PARSER_INHERIT ( MIHBaseTLVParser );
176         SENF_PARSER_VECTOR  ( value, bytes(length), senf::MACAddressParser );
177         SENF_PARSER_FINALIZE( TestMacAddressTLVPacketParser );
178     };
179
180     struct TestMacAddressTLVPacketType
181         : public PacketTypeBase,
182           public PacketTypeMixin<TestMacAddressTLVPacketType>
183     {
184         typedef PacketTypeMixin<TestMacAddressTLVPacketType> mixin;
185         typedef TestMacAddressTLVPacketParser parser;
186
187         using mixin::nextPacketRange;
188         using mixin::init;
189         using mixin::initSize;
190
191         static void finalize(ConcretePacket<TestMacAddressTLVPacketType> p) {
192             p->finalize();
193         }
194     };
195     typedef ConcretePacket<TestMacAddressTLVPacketType> TestMacAddressTLVPacket;
196 }
197
198 SENF_AUTO_UNIT_TEST(TestMacAddressTLVPacket_create)
199 {
200     TestMacAddressTLVPacket tlvPacket (TestMacAddressTLVPacket::create());
201     tlvPacket->type() = 42;
202     tlvPacket->value().push_back( senf::MACAddress::from_string("01:23:45:67:89:ab") );
203     tlvPacket->value().push_back( senf::MACAddress::from_string("cd:ef:01:23:45:67") );
204     tlvPacket.finalizeThis();
205
206     unsigned char data[] = {
207         0x2a, // type
208         0x0c, // length
209         0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67  // value
210     };
211     SENF_CHECK_EQUAL_COLLECTIONS(
212             data, data+sizeof(data), tlvPacket.data().begin(), tlvPacket.data().end() );
213 }
214
215
216 //-/////////////////////////////////////////////////////////////////////////////////////////////////
217 #undef prefix_
218
219 \f
220 // Local Variables:
221 // mode: c++
222 // fill-column: 100
223 // c-file-style: "senf"
224 // indent-tabs-mode: nil
225 // ispell-local-dictionary: "american"
226 // compile-command: "scons -u test"
227 // comment-column: 40
228 // End: