Packets/80221Bundle: integrated GenericTLVRegistry
[senf.git] / senf / Packets / 80221Bundle / MIHPacket.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2009
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 MIHPacket unit tests */
25
26 //#include "MIHPacket.test.hh"
27 //#include "MIHPacket.test.ih"
28
29 // Custom includes
30 #include "MIHPacket.hh"
31 #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
32
33 #include <senf/Utils/auto_unit_test.hh>
34 #include <boost/test/test_tools.hpp>
35
36 #define prefix_
37 ///////////////////////////////cc.p////////////////////////////////////////
38 using namespace senf;
39
40 BOOST_AUTO_UNIT_TEST(MIHPacket_MIHFId)
41 {
42     MIHFId id ( MACAddress::from_string("01:02:03:04:05:06"));
43     BOOST_CHECK_EQUAL( id.type(), MIHFId::MACAddress);
44     BOOST_CHECK_EQUAL( id, MIHFId( MACAddress::from_string("01:02:03:04:05:06")));
45     BOOST_CHECK( id != MIHFId( MACAddress::from_string("01:02:03:04:05:07")));
46     BOOST_CHECK( id != MIHFId( INet4Address::from_string("128.129.130.131")));
47     BOOST_CHECK( id < MIHFId( MACAddress::from_string("01:02:03:04:05:07")));
48     BOOST_CHECK( id < MIHFId( INet4Address::from_string("128.129.130.131")));
49 }
50
51 BOOST_AUTO_UNIT_TEST(MIHPacket_msgId)
52 {
53     MIHPacket mihPacket (MIHPacket::create());
54     mihPacket->sid() = 4;
55     mihPacket->opcode() = 3;
56     mihPacket->aid() = 42;
57     BOOST_CHECK_EQUAL( mihPacket->messageId(), 0x4c2a );        
58 }
59
60 BOOST_AUTO_UNIT_TEST(MIHPacket_create_eth)
61 {
62     EthernetPacket eth (EthernetPacket::create());
63     MIHPacket mihPacket (MIHPacket::createAfter(eth));
64     eth.finalizeAll();
65     BOOST_CHECK_EQUAL( eth->type_length(), 0x8917);
66     std::ostringstream oss (std::ostringstream::out);
67     SENF_CHECK_NO_THROW( eth.dump( oss));
68 }
69
70 BOOST_AUTO_UNIT_TEST(MIHPacket_create_string)
71 {
72     MIHPacket mihPacket (MIHPacket::create());
73     // set some fields
74     mihPacket->fragmentNr() = 42;
75     mihPacket->transactionId() = 21;
76     mihPacket->src_mihfId().setString( "senf@berlios.de");
77     mihPacket->dst_mihfId().setString( "test");
78     mihPacket.finalizeThis();
79
80     unsigned char data[] = {
81             // MIH header
82             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x17,
83             // source MIHF_ID TLV:
84             0x01, 0x0f, // type, length
85             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
86             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
87             // destination MIHF_ID TLV:
88             0x02, 0x04, 0x74, 0x65, 0x73, 0x74
89     };
90     BOOST_CHECK(equal( mihPacket.data().begin(), mihPacket.data().end(), data ));
91     BOOST_CHECK_EQUAL( mihPacket->src_mihfId().asString(), "senf@berlios.de");
92     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().asString(), "test");
93
94     // the maximum length of a MIHF_ID is 253 octets
95     BOOST_CHECK_THROW( mihPacket->dst_mihfId().setString( std::string(254, 'x')), std::length_error);
96
97     // now expand a MIHF_ID
98     mihPacket->dst_mihfId().maxLengthValue(253);
99     mihPacket->dst_mihfId().setString( std::string(200, 'x'));
100     mihPacket.finalizeThis();
101
102     BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 17 + 203));
103     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 17 + 203);
104     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 200u);
105     BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 203u);
106
107     std::ostringstream oss (std::ostringstream::out);
108     SENF_CHECK_NO_THROW( mihPacket.dump( oss));
109 }
110
111
112 BOOST_AUTO_UNIT_TEST(MIHPacket_create_mac)
113 {
114     MIHPacket mihPacket (MIHPacket::create());
115     // set some fields
116     mihPacket->fragmentNr() = 42;
117     mihPacket->transactionId() = 21;
118     mihPacket->src_mihfId().setMACAddress( MACAddress::from_string("01:02:03:04:05:06"));
119     mihPacket->dst_mihfId().setMACAddress( MACAddress::from_string("07:08:09:0a:0b:0c"));
120     mihPacket.finalizeThis();
121
122     unsigned char data[] = {
123             // MIH header
124             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x1c,
125             // source MIHF_ID TLV:
126             0x01, 0x0c, // type, length
127             0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04, 0x5c, 0x05, 0x5c, 0x06, // value (nai-encoded)
128             // destination MIHF_ID TLV:
129             0x02, 0x0c,  // type, length
130             0x5c, 0x07, 0x5c, 0x08, 0x5c, 0x09, 0x5c, 0x0a, 0x5c, 0x0b, 0x5c, 0x0c  // value (nai-encoded)
131     };
132     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
133             mihPacket.data().begin(), mihPacket.data().end() );
134     BOOST_CHECK_EQUAL(
135             mihPacket->src_mihfId().asMACAddress(),
136             MACAddress::from_string("01:02:03:04:05:06"));
137     BOOST_CHECK_EQUAL(
138             mihPacket->dst_mihfId().asMACAddress(),
139             MACAddress::from_string("07:08:09:0a:0b:0c"));
140 }
141
142
143 BOOST_AUTO_UNIT_TEST(MIHPacket_create_inet4)
144 {
145     MIHPacket mihPacket (MIHPacket::create());
146     // set some fields
147     mihPacket->fragmentNr() = 42;
148     mihPacket->transactionId() = 21;
149     mihPacket->src_mihfId().setINet4Address( INet4Address::from_string("128.129.130.131"));
150     mihPacket->dst_mihfId().setINet4Address( INet4Address::from_string("132.133.134.135"));
151     mihPacket.finalizeThis();
152
153     unsigned char data[] = {
154             // MIH header
155             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x14,
156             // source MIHF_ID TLV:
157             0x01, 0x08, // type, length
158             0x5c, 0x80, 0x5c, 0x81, 0x5c, 0x82, 0x5c, 0x83, // value (nai-encoded)
159             // destination MIHF_ID TLV:
160             0x02, 0x08, // type, length
161             0x5c, 0x84, 0x5c, 0x85, 0x5c, 0x86, 0x5c, 0x87  // value (nai-encoded)
162     };
163     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
164             mihPacket.data().begin(), mihPacket.data().end() );
165     BOOST_CHECK_EQUAL(
166             mihPacket->src_mihfId().asINet4Address(),
167             INet4Address::from_string("128.129.130.131"));
168     BOOST_CHECK_EQUAL(
169             mihPacket->dst_mihfId().asINet4Address(),
170             INet4Address::from_string("132.133.134.135"));
171 }
172
173
174 BOOST_AUTO_UNIT_TEST(MIHPacket_create_inet6)
175 {
176     MIHPacket mihPacket (MIHPacket::create());
177     // set some fields
178     mihPacket->fragmentNr() = 42;
179     mihPacket->transactionId() = 21;
180     mihPacket->src_mihfId().setINet6Address( INet6Address::from_string("::ffff:1.2.3.4"));
181     mihPacket->dst_mihfId().setINet6Address( INet6Address::from_string("::ffff:5.6.7.8"));
182     mihPacket.finalizeThis();
183
184     unsigned char data[] = {
185             // MIH header
186             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x44,
187             // source MIHF_ID TLV:
188             0x01, 0x20, // type, length
189             // value (nai-encoded):
190             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
191             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
192             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff,
193             0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04,
194             // destination MIHF_ID TLV:
195             0x02, 0x20, // type, length
196             // value (nai-encoded):
197             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
198             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
199             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff,
200             0x5c, 0x05, 0x5c, 0x06, 0x5c, 0x07, 0x5c, 0x08
201     };
202     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
203             mihPacket.data().begin(), mihPacket.data().end() );
204     BOOST_CHECK_EQUAL(
205             mihPacket->src_mihfId().asINet6Address(),
206             INet6Address::from_string("::ffff:1.2.3.4"));
207     BOOST_CHECK_EQUAL(
208             mihPacket->dst_mihfId().asINet6Address(),
209             INet6Address::from_string("::ffff:5.6.7.8") );
210 }
211
212
213 BOOST_AUTO_UNIT_TEST(MIHPayload_parse)
214 {
215     unsigned char data[] = {
216             // MIH header
217             0x10, 0x54, 0x00, 0x00, 0x00, 0x15,
218             // variable payload length:
219             0x00, 0x2a,
220             // source MIHF_ID TLV:
221             0x01, 0x0f, // type, length
222             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
223             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value ("senf@berlios.de")
224             // destination MIHF_ID TLV:
225             0x02, 0x04, 0x74, 0x65, 0x73, 0x74,  // type, length, value ("test")
226             // MIH Payload (two test tlvs)
227             // first test tlv
228             0x42, // type
229             0x0a, // first bit not set, length=10
230             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, // value
231             // second test tlv
232             0x43, // type
233             0x05, // first bit not set, length=5
234             0x1a, 0x2b, 0x3c, 0x4d, 0x5e // value
235     };
236
237     MIHPacket mihPacket (MIHPacket::create(data));
238     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 42u);
239
240     BOOST_REQUIRE( mihPacket.next().is<MIHGenericPayloadPacket>() );
241     MIHGenericPayloadPacket mihPayload (mihPacket.next().as<MIHGenericPayloadPacket>());
242
243     BOOST_CHECK_EQUAL( mihPayload->tlvList().size(), 2u);
244     MIHGenericPayloadPacket::Parser::tlvList_t::container tlvListContainer (
245             mihPayload->tlvList());
246
247     MIHGenericTLVParser tlv1 = *tlvListContainer.begin();
248     BOOST_CHECK_EQUAL( tlv1.type(), 0x42);
249     BOOST_CHECK_EQUAL( tlv1.length(), 0x0au);
250     BOOST_CHECK_EQUAL( tlv1.value().size(), 0x0a);
251
252     MIHGenericTLVParser tlv2 = *boost::next(tlvListContainer.begin());
253     BOOST_CHECK_EQUAL( tlv2.type(), 0x43);
254     BOOST_CHECK_EQUAL( tlv2.length(), 0x05u);
255     BOOST_CHECK_EQUAL( tlv2.value().size(), 0x05);
256     
257     std::ostringstream oss (std::ostringstream::out);
258     SENF_CHECK_NO_THROW( mihPayload.dump( oss));
259 }
260
261
262 BOOST_AUTO_UNIT_TEST(MIHPayload_create)
263 {
264     MIHPacket mihPacket (MIHPacket::create());
265     mihPacket->fragmentNr() = 42;
266     mihPacket->transactionId() = 21;
267     mihPacket->src_mihfId().setString( "senf@berlios.de");
268     mihPacket->dst_mihfId().setString( "test");
269
270     MIHGenericPayloadPacket mihPayload (MIHGenericPayloadPacket::createAfter(mihPacket));
271     MIHGenericPayloadPacket::Parser::tlvList_t::container tlvListContainer (
272             mihPayload->tlvList() );
273     
274     unsigned char tlv1_value[] = {
275            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
276     MIHGenericTLVParser tlv1 ( tlvListContainer.push_back_space());
277     tlv1.type() = 0x42;
278     tlv1.value( tlv1_value);
279
280     unsigned char tlv2_value[] = {
281             0x1a, 0x2b, 0x3c, 0x4d, 0x5e };
282     MIHGenericTLVParser tlv2 ( tlvListContainer.push_back_space());
283     tlv2.type() = 0x43;
284     tlv2.value( tlv2_value);
285
286     mihPacket.finalizeAll();
287
288     unsigned char data[] = {
289             // MIH header
290             0x10, 0x54, 0x00, 0x00, 0x00, 0x15,
291             // variable payload length:
292             0x00, 0x2a,
293             // source MIHF_ID TLV:
294             0x01, 0x0f, // type, length
295             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
296             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value ("senf@berlios.de")
297             // destination MIHF_ID TLV:
298             0x02, 0x04, 0x74, 0x65, 0x73, 0x74,  // type, length, value ("test")
299             // MIH Payload (two test tlvs)
300             // first test tlv
301             0x42, // type
302             0x0a, // first bit not set, length=10
303             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, // value
304             // second test tlv
305             0x43, // type
306             0x05, // first bit not set, length=5
307             0x1a, 0x2b, 0x3c, 0x4d, 0x5e // value
308     };
309     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
310             mihPacket.data().begin(), mihPacket.data().end() );    
311 }
312
313
314 ///////////////////////////////cc.e////////////////////////////////////////
315 #undef prefix_
316
317 \f
318 // Local Variables:
319 // mode: c++
320 // fill-column: 100
321 // c-file-style: "senf"
322 // indent-tabs-mode: nil
323 // ispell-local-dictionary: "american"
324 // compile-command: "scons -u test"
325 // comment-column: 40
326 // End: