switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / 80221Bundle / MIHPacket.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2009
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Thorsten Horstmann <tho@berlios.de>
27
28 /** \file
29     \brief MIHPacket unit tests */
30
31 //#include "MIHPacket.test.hh"
32 //#include "MIHPacket.test.ih"
33
34 // Custom includes
35 #include "MIHPacket.hh"
36 #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
37
38 #include <senf/Utils/auto_unit_test.hh>
39 #include <boost/test/test_tools.hpp>
40
41 #define prefix_
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
43 using namespace senf;
44
45 SENF_AUTO_UNIT_TEST(MIHPacket_msgId)
46 {
47     MIHPacket mihPacket (MIHPacket::create());
48     mihPacket->sid() = 4;
49     mihPacket->opcode() = 3;
50     mihPacket->aid() = 42;
51     BOOST_CHECK_EQUAL( mihPacket->messageId(), 0x4c2a );
52 }
53
54 SENF_AUTO_UNIT_TEST(MIHPacket_create_eth)
55 {
56     EthernetPacket eth (EthernetPacket::create());
57     MIHPacket mihPacket (MIHPacket::createAfter(eth));
58     eth.finalizeAll();
59     BOOST_CHECK_EQUAL( eth->type_length(), 0x8917);
60     std::ostringstream oss (std::ostringstream::out);
61     SENF_CHECK_NO_THROW( eth.dump( oss));
62 }
63
64 SENF_AUTO_UNIT_TEST(MIHPacket_create_string)
65 {
66     MIHPacket mihPacket (MIHPacket::create());
67     // set some fields
68     mihPacket->fragmentNr() = 42;
69     mihPacket->transactionId() = 21;
70     mihPacket->src_mihfId().value( "senf@berlios.de");
71     mihPacket->dst_mihfId().value( "test");
72     mihPacket.finalizeThis();
73
74     unsigned char data[] = {
75             // MIH header
76             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19,
77             // source MIHF_ID TLV:
78             0x01, 0x10, // type, length
79             0x0f,  // value-length
80             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
81             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
82             // destination MIHF_ID TLV:
83             0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74
84     };
85     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
86             mihPacket.data().begin(), mihPacket.data().end() );
87     BOOST_CHECK_EQUAL( mihPacket->src_mihfId().valueAsString(), "senf@berlios.de");
88     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().valueAsString(), "test");
89
90     // the maximum length of a MIHF_ID is 253 octets
91     BOOST_CHECK_THROW( mihPacket->dst_mihfId().value( std::string(254, 'x')), std::length_error);
92     // now expand a MIHF_ID
93     // first the tricky one: when setting the maximum id length to 128 the TLV length field
94     // is set to 129 and therefore expanded to 2 bytes; the id-length field is still 1 byte long
95     mihPacket->dst_mihfId().maxIdLength(128);
96     mihPacket->dst_mihfId().value( std::string(128, 'x'));
97     mihPacket.finalizeThis();
98     // packet size is now MIH header (8 bytes) + src MIHIFId TLV (18 bytes) +
99     // dst MIHIFId TLV (1 byte type + 2 byte TLV length + 1 byte id length + 128 id value)
100     BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 18 + 1+2+1+128));
101     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 18 + 1+2+1+128);
102     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 1+128);
103     BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 1+2+1+128);
104     // now we extend the dst id to 129 bytes; than we have 2 bytes tlv length and 2 bytes
105     // id-length field
106     mihPacket->dst_mihfId().maxIdLength(129);
107     mihPacket->dst_mihfId().value( std::string(129, 'x'));
108     mihPacket.finalizeThis();
109     // packet size is now MIH header (8 bytes) + src MIHIFId TLV (18 bytes) +
110     // dst MIHIFId TLV (1 byte type + 2 byte TLV length + 2 byte id length + 128 id value)
111     BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 18 + 1+2+2+129));
112     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 18 + 1+2+2+129);
113     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 2+129);
114     BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 1+2+2+129);
115     // finally we shrink to dst id field
116     mihPacket->dst_mihfId().value( "test");
117     mihPacket.finalizeThis();
118     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
119             mihPacket.data().begin(), mihPacket.data().end() );
120
121     std::ostringstream oss (std::ostringstream::out);
122     SENF_CHECK_NO_THROW( mihPacket.dump( oss));
123 }
124
125
126 SENF_AUTO_UNIT_TEST(MIHPacket_create_mac)
127 {
128     MACAddress srcMac ( MACAddress::from_string("01:02:03:04:05:06"));
129     MACAddress dstMac ( MACAddress::from_string("07:08:09:0a:0b:0c"));
130     MIHPacket mihPacket (MIHPacket::create());
131     // set some fields
132     mihPacket->fragmentNr() = 42;
133     mihPacket->transactionId() = 21;
134     mihPacket->src_mihfId().value( srcMac);
135     mihPacket->dst_mihfId().value( dstMac);
136     mihPacket.finalizeThis();
137
138     unsigned char data[] = {
139             // MIH header
140             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x1e,
141             // source MIHF_ID TLV:
142             0x01, 0x0d, // type, length
143             0x0c,       // value-length
144             0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04, 0x5c, 0x05, 0x5c, 0x06, // value (nai-encoded)
145             // destination MIHF_ID TLV:
146             0x02, 0x0d, // type, length
147             0x0c,       // value-length
148             0x5c, 0x07, 0x5c, 0x08, 0x5c, 0x09, 0x5c, 0x0a, 0x5c, 0x0b, 0x5c, 0x0c  // value (nai-encoded)
149     };
150     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
151             mihPacket.data().begin(), mihPacket.data().end() );
152     BOOST_CHECK_EQUAL( mihPacket->src_mihfId().valueAsMACAddress(), srcMac);
153     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().valueAsMACAddress(), dstMac);
154     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().valueAs( MIHFId::MACAddress), MIHFId(dstMac) );
155     BOOST_CHECK( mihPacket->src_mihfId().valueEquals(srcMac));
156 }
157
158
159 SENF_AUTO_UNIT_TEST(MIHPacket_create_inet4)
160 {
161     MIHPacket mihPacket (MIHPacket::create());
162     // set some fields
163     mihPacket->fragmentNr() = 42;
164     mihPacket->transactionId() = 21;
165     mihPacket->src_mihfId().value( INet4Address::from_string("128.129.130.131"));
166     mihPacket->dst_mihfId().value( INet4Address::from_string("132.133.134.135"));
167     mihPacket.finalizeThis();
168
169     unsigned char data[] = {
170             // MIH header
171             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x16,
172             // source MIHF_ID TLV:
173             0x01, 0x09, // type, length
174             0x08,       // value-length
175             0x5c, 0x80, 0x5c, 0x81, 0x5c, 0x82, 0x5c, 0x83, // value (nai-encoded)
176             // destination MIHF_ID TLV:
177             0x02, 0x09, // type, length
178             0x08,       // value-length
179             0x5c, 0x84, 0x5c, 0x85, 0x5c, 0x86, 0x5c, 0x87  // value (nai-encoded)
180     };
181     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
182             mihPacket.data().begin(), mihPacket.data().end() );
183     BOOST_CHECK_EQUAL(
184             mihPacket->src_mihfId().valueAsINet4Address(),
185             INet4Address::from_string("128.129.130.131"));
186     BOOST_CHECK_EQUAL(
187             mihPacket->dst_mihfId().valueAsINet4Address(),
188             INet4Address::from_string("132.133.134.135"));
189 }
190
191
192 SENF_AUTO_UNIT_TEST(MIHPacket_create_inet6)
193 {
194     MIHPacket mihPacket (MIHPacket::create());
195     // set some fields
196     mihPacket->fragmentNr() = 42;
197     mihPacket->transactionId() = 21;
198     mihPacket->src_mihfId().value( INet6Address::from_string("::ffff:1.2.3.4"));
199     mihPacket->dst_mihfId().value( INet6Address::from_string("::ffff:5.6.7.8"));
200     mihPacket.finalizeThis();
201
202     unsigned char data[] = {
203             // MIH header
204             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x46,
205             // source MIHF_ID TLV:
206             0x01, 0x21, // type, length
207             0x20,       // value-length
208             // value (nai-encoded):
209             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
210             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
211             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff,
212             0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04,
213             // destination MIHF_ID TLV:
214             0x02, 0x21, // type, length
215             0x20,       // value-length
216             // value (nai-encoded):
217             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
218             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
219             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff,
220             0x5c, 0x05, 0x5c, 0x06, 0x5c, 0x07, 0x5c, 0x08
221     };
222     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
223             mihPacket.data().begin(), mihPacket.data().end() );
224     BOOST_CHECK_EQUAL(
225             mihPacket->src_mihfId().valueAsINet6Address(),
226             INet6Address::from_string("::ffff:1.2.3.4"));
227     BOOST_CHECK_EQUAL(
228             mihPacket->dst_mihfId().valueAsINet6Address(),
229             INet6Address::from_string("::ffff:5.6.7.8") );
230 }
231
232
233 SENF_AUTO_UNIT_TEST(MIHPayload_parse)
234 {
235     unsigned char data[] = {
236             // MIH header
237             0x10, 0x54, 0x00, 0x00, 0x00, 0x15,
238             // variable payload length:
239             0x00, 0x29,
240             // source MIHF_ID TLV:
241             0x01, 0x10, // type, length
242             0x0f,  // value-length
243             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
244             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
245             // destination MIHF_ID TLV:
246             0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74,
247             // MIH Payload (two test tlvs)
248             // first test tlv
249             0x42, // type
250             0x0a, // first bit not set, length=10
251             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, // value
252             // second test tlv
253             0x0c, // type
254             0x04, // first bit not set, length=4
255             0x1a, 0x2b, 0x3c, 0x4d // value
256     };
257
258     MIHPacket mihPacket (MIHPacket::create(data));
259     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 41u);
260
261     BOOST_REQUIRE( mihPacket.next().is<MIHGenericPayloadPacket>() );
262     MIHGenericPayloadPacket mihPayload (mihPacket.next().as<MIHGenericPayloadPacket>());
263
264     BOOST_CHECK_EQUAL( mihPayload->tlvList().size(), 2u);
265     MIHGenericPayloadPacket::Parser::tlvList_t::container tlvListContainer (
266             mihPayload->tlvList());
267
268     MIHGenericTLVParser tlv1 = *tlvListContainer.begin();
269     BOOST_CHECK_EQUAL( tlv1.type(), 0x42);
270     BOOST_CHECK_EQUAL( tlv1.length(), 0x0au);
271     BOOST_CHECK_EQUAL( tlv1.value().size(), 0x0a);
272
273     MIHGenericTLVParser tlv2 = *boost::next(tlvListContainer.begin());
274     BOOST_CHECK_EQUAL( tlv2.type(), 0x0c);
275     BOOST_CHECK_EQUAL( tlv2.length(), 0x04u);
276     BOOST_CHECK_EQUAL( tlv2.value().size(), 0x04);
277
278     std::ostringstream oss (std::ostringstream::out);
279     SENF_CHECK_NO_THROW( mihPayload.dump( oss));
280 }
281
282
283 SENF_AUTO_UNIT_TEST(MIHPayload_create)
284 {
285     MIHPacket mihPacket (MIHPacket::create());
286     mihPacket->fragmentNr() = 42;
287     mihPacket->transactionId() = 21;
288     mihPacket->src_mihfId().value( "senf@berlios.de");
289     mihPacket->dst_mihfId().value( "test");
290
291     MIHGenericPayloadPacket mihPayload (MIHGenericPayloadPacket::createAfter(mihPacket));
292     MIHGenericPayloadPacket::Parser::tlvList_t::container tlvListContainer (
293             mihPayload->tlvList() );
294
295     unsigned char tlv1_value[] = {
296            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
297     MIHGenericTLVParser tlv1 ( tlvListContainer.push_back_space());
298     tlv1.type() = 0x42;
299     tlv1.value( tlv1_value);
300
301     unsigned char tlv2_value[] = {
302             0x1a, 0x2b, 0x3c, 0x4d };
303     MIHGenericTLVParser tlv2 ( tlvListContainer.push_back_space());
304     tlv2.type() = 0x43;
305     tlv2.value( tlv2_value);
306
307     mihPacket.finalizeAll();
308
309     unsigned char data[] = {
310             // MIH header
311             0x10, 0x54, 0x00, 0x00, 0x00, 0x15,
312             // variable payload length:
313             0x00, 0x2b,
314             // source MIHF_ID TLV:
315             0x01, 0x10, // type, length
316             0x0f,  // value-length
317             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
318             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
319             // destination MIHF_ID TLV:
320             0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74,
321             // MIH Payload (two test tlvs)
322             // first test tlv
323             0x42, // type
324             0x0a, // first bit not set, length=10
325             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, // value
326             // second test tlv
327             0x43, // type
328             0x04, // first bit not set, length=4
329             0x1a, 0x2b, 0x3c, 0x4d // value
330     };
331     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
332             mihPacket.data().begin(), mihPacket.data().end() );
333 }
334
335 SENF_AUTO_UNIT_TEST(Test_MIHFIdTLV)
336 {
337     unsigned char data[] = {
338             // MIH header
339             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x06,
340             // source MIHF_ID TLV:
341             0x01, 0x01, // type, length
342             0x00,       // value-length
343             // destination MIHF_ID TLV:
344             0x02, 0x01, // type, length
345             0x00        // value-length
346     };
347
348     MIHPacket mihPacket (MIHPacket::create(data));
349     BOOST_CHECK( mihPacket->src_mihfId().valueEquals( MIHFId::Multicast) );
350     BOOST_CHECK( mihPacket->dst_mihfId().valueEquals( MIHFId::Multicast) );
351 }
352
353 //-/////////////////////////////////////////////////////////////////////////////////////////////////
354 #undef prefix_
355
356 \f
357 // Local Variables:
358 // mode: c++
359 // fill-column: 100
360 // c-file-style: "senf"
361 // indent-tabs-mode: nil
362 // ispell-local-dictionary: "american"
363 // compile-command: "scons -u test"
364 // comment-column: 40
365 // End: