f339826016c02c5711b3b26abb51f3236a94c637
[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 SENF_AUTO_UNIT_TEST(MIHPacket_msgId)
41 {
42     MIHPacket mihPacket (MIHPacket::create());
43     mihPacket->sid() = 4;
44     mihPacket->opcode() = 3;
45     mihPacket->aid() = 42;
46     BOOST_CHECK_EQUAL( mihPacket->messageId(), 0x4c2a );
47 }
48
49 SENF_AUTO_UNIT_TEST(MIHPacket_create_eth)
50 {
51     EthernetPacket eth (EthernetPacket::create());
52     MIHPacket mihPacket (MIHPacket::createAfter(eth));
53     eth.finalizeAll();
54     BOOST_CHECK_EQUAL( eth->type_length(), 0x8917);
55     std::ostringstream oss (std::ostringstream::out);
56     SENF_CHECK_NO_THROW( eth.dump( oss));
57 }
58
59 SENF_AUTO_UNIT_TEST(MIHPacket_create_string)
60 {
61     MIHPacket mihPacket (MIHPacket::create());
62     // set some fields
63     mihPacket->fragmentNr() = 42;
64     mihPacket->transactionId() = 21;
65     mihPacket->src_mihfId().value( "senf@berlios.de");
66     mihPacket->dst_mihfId().value( "test");
67     mihPacket.finalizeThis();
68
69     unsigned char data[] = {
70             // MIH header
71             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19,
72             // source MIHF_ID TLV:
73             0x01, 0x10, // type, length
74             0x0f,  // value-length
75             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
76             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
77             // destination MIHF_ID TLV:
78             0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74
79     };
80     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
81             mihPacket.data().begin(), mihPacket.data().end() );
82     BOOST_CHECK_EQUAL( mihPacket->src_mihfId().valueAsString(), "senf@berlios.de");
83     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().valueAsString(), "test");
84
85     // the maximum length of a MIHF_ID is 253 octets
86     BOOST_CHECK_THROW( mihPacket->dst_mihfId().value( std::string(254, 'x')), std::length_error);
87     // now expand a MIHF_ID
88     // first the tricky one: when setting the maximum id length to 128 the TLV length field
89     // is set to 129 and therefore expanded to 2 bytes; the id-length field is still 1 byte long
90     mihPacket->dst_mihfId().maxIdLength(128);
91     mihPacket->dst_mihfId().value( std::string(128, 'x'));
92     mihPacket.finalizeThis();
93     // packet size is now MIH header (8 bytes) + src MIHIFId TLV (18 bytes) +
94     // dst MIHIFId TLV (1 byte type + 2 byte TLV length + 1 byte id length + 128 id value)
95     BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 18 + 1+2+1+128));
96     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 18 + 1+2+1+128);
97     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 1+128);
98     BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 1+2+1+128);
99     // now we extend the dst id to 129 bytes; than we have 2 bytes tlv length and 2 bytes
100     // id-length field
101     mihPacket->dst_mihfId().maxIdLength(129);
102     mihPacket->dst_mihfId().value( std::string(129, 'x'));
103     mihPacket.finalizeThis();
104     // packet size is now MIH header (8 bytes) + src MIHIFId TLV (18 bytes) +
105     // dst MIHIFId TLV (1 byte type + 2 byte TLV length + 2 byte id length + 128 id value)
106     BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 18 + 1+2+2+129));
107     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 18 + 1+2+2+129);
108     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 2+129);
109     BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 1+2+2+129);
110     // finally we shrink to dst id field
111     mihPacket->dst_mihfId().value( "test");
112     mihPacket.finalizeThis();
113     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
114             mihPacket.data().begin(), mihPacket.data().end() );
115
116     std::ostringstream oss (std::ostringstream::out);
117     SENF_CHECK_NO_THROW( mihPacket.dump( oss));
118 }
119
120
121 SENF_AUTO_UNIT_TEST(MIHPacket_create_mac)
122 {
123     MACAddress srcMac ( MACAddress::from_string("01:02:03:04:05:06"));
124     MACAddress dstMac ( MACAddress::from_string("07:08:09:0a:0b:0c"));
125     MIHPacket mihPacket (MIHPacket::create());
126     // set some fields
127     mihPacket->fragmentNr() = 42;
128     mihPacket->transactionId() = 21;
129     mihPacket->src_mihfId().value( srcMac);
130     mihPacket->dst_mihfId().value( dstMac);
131     mihPacket.finalizeThis();
132
133     unsigned char data[] = {
134             // MIH header
135             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x1e,
136             // source MIHF_ID TLV:
137             0x01, 0x0d, // type, length
138             0x0c,       // value-length
139             0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04, 0x5c, 0x05, 0x5c, 0x06, // value (nai-encoded)
140             // destination MIHF_ID TLV:
141             0x02, 0x0d, // type, length
142             0x0c,       // value-length
143             0x5c, 0x07, 0x5c, 0x08, 0x5c, 0x09, 0x5c, 0x0a, 0x5c, 0x0b, 0x5c, 0x0c  // value (nai-encoded)
144     };
145     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
146             mihPacket.data().begin(), mihPacket.data().end() );
147     BOOST_CHECK_EQUAL( mihPacket->src_mihfId().valueAsMACAddress(), srcMac);
148     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().valueAsMACAddress(), dstMac);
149     BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().valueAs( MIHFId::MACAddress), MIHFId(dstMac) );
150     BOOST_CHECK( mihPacket->src_mihfId().valueEquals(srcMac));
151 }
152
153
154 SENF_AUTO_UNIT_TEST(MIHPacket_create_inet4)
155 {
156     MIHPacket mihPacket (MIHPacket::create());
157     // set some fields
158     mihPacket->fragmentNr() = 42;
159     mihPacket->transactionId() = 21;
160     mihPacket->src_mihfId().value( INet4Address::from_string("128.129.130.131"));
161     mihPacket->dst_mihfId().value( INet4Address::from_string("132.133.134.135"));
162     mihPacket.finalizeThis();
163
164     unsigned char data[] = {
165             // MIH header
166             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x16,
167             // source MIHF_ID TLV:
168             0x01, 0x09, // type, length
169             0x08,       // value-length
170             0x5c, 0x80, 0x5c, 0x81, 0x5c, 0x82, 0x5c, 0x83, // value (nai-encoded)
171             // destination MIHF_ID TLV:
172             0x02, 0x09, // type, length
173             0x08,       // value-length
174             0x5c, 0x84, 0x5c, 0x85, 0x5c, 0x86, 0x5c, 0x87  // value (nai-encoded)
175     };
176     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
177             mihPacket.data().begin(), mihPacket.data().end() );
178     BOOST_CHECK_EQUAL(
179             mihPacket->src_mihfId().valueAsINet4Address(),
180             INet4Address::from_string("128.129.130.131"));
181     BOOST_CHECK_EQUAL(
182             mihPacket->dst_mihfId().valueAsINet4Address(),
183             INet4Address::from_string("132.133.134.135"));
184 }
185
186
187 SENF_AUTO_UNIT_TEST(MIHPacket_create_inet6)
188 {
189     MIHPacket mihPacket (MIHPacket::create());
190     // set some fields
191     mihPacket->fragmentNr() = 42;
192     mihPacket->transactionId() = 21;
193     mihPacket->src_mihfId().value( INet6Address::from_string("::ffff:1.2.3.4"));
194     mihPacket->dst_mihfId().value( INet6Address::from_string("::ffff:5.6.7.8"));
195     mihPacket.finalizeThis();
196
197     unsigned char data[] = {
198             // MIH header
199             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x46,
200             // source MIHF_ID TLV:
201             0x01, 0x21, // type, length
202             0x20,       // value-length
203             // value (nai-encoded):
204             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
205             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
206             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff,
207             0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04,
208             // destination MIHF_ID TLV:
209             0x02, 0x21, // type, length
210             0x20,       // value-length
211             // value (nai-encoded):
212             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
213             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00,
214             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff,
215             0x5c, 0x05, 0x5c, 0x06, 0x5c, 0x07, 0x5c, 0x08
216     };
217     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
218             mihPacket.data().begin(), mihPacket.data().end() );
219     BOOST_CHECK_EQUAL(
220             mihPacket->src_mihfId().valueAsINet6Address(),
221             INet6Address::from_string("::ffff:1.2.3.4"));
222     BOOST_CHECK_EQUAL(
223             mihPacket->dst_mihfId().valueAsINet6Address(),
224             INet6Address::from_string("::ffff:5.6.7.8") );
225 }
226
227
228 SENF_AUTO_UNIT_TEST(MIHPayload_parse)
229 {
230     unsigned char data[] = {
231             // MIH header
232             0x10, 0x54, 0x00, 0x00, 0x00, 0x15,
233             // variable payload length:
234             0x00, 0x29,
235             // source MIHF_ID TLV:
236             0x01, 0x10, // type, length
237             0x0f,  // value-length
238             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
239             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
240             // destination MIHF_ID TLV:
241             0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74,
242             // MIH Payload (two test tlvs)
243             // first test tlv
244             0x42, // type
245             0x0a, // first bit not set, length=10
246             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, // value
247             // second test tlv
248             0x0c, // type
249             0x04, // first bit not set, length=4
250             0x1a, 0x2b, 0x3c, 0x4d // value
251     };
252
253     MIHPacket mihPacket (MIHPacket::create(data));
254     BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 41u);
255
256     BOOST_REQUIRE( mihPacket.next().is<MIHGenericPayloadPacket>() );
257     MIHGenericPayloadPacket mihPayload (mihPacket.next().as<MIHGenericPayloadPacket>());
258
259     BOOST_CHECK_EQUAL( mihPayload->tlvList().size(), 2u);
260     MIHGenericPayloadPacket::Parser::tlvList_t::container tlvListContainer (
261             mihPayload->tlvList());
262
263     MIHGenericTLVParser tlv1 = *tlvListContainer.begin();
264     BOOST_CHECK_EQUAL( tlv1.type(), 0x42);
265     BOOST_CHECK_EQUAL( tlv1.length(), 0x0au);
266     BOOST_CHECK_EQUAL( tlv1.value().size(), 0x0a);
267
268     MIHGenericTLVParser tlv2 = *boost::next(tlvListContainer.begin());
269     BOOST_CHECK_EQUAL( tlv2.type(), 0x0c);
270     BOOST_CHECK_EQUAL( tlv2.length(), 0x04u);
271     BOOST_CHECK_EQUAL( tlv2.value().size(), 0x04);
272
273     std::ostringstream oss (std::ostringstream::out);
274     SENF_CHECK_NO_THROW( mihPayload.dump( oss));
275 }
276
277
278 SENF_AUTO_UNIT_TEST(MIHPayload_create)
279 {
280     MIHPacket mihPacket (MIHPacket::create());
281     mihPacket->fragmentNr() = 42;
282     mihPacket->transactionId() = 21;
283     mihPacket->src_mihfId().value( "senf@berlios.de");
284     mihPacket->dst_mihfId().value( "test");
285
286     MIHGenericPayloadPacket mihPayload (MIHGenericPayloadPacket::createAfter(mihPacket));
287     MIHGenericPayloadPacket::Parser::tlvList_t::container tlvListContainer (
288             mihPayload->tlvList() );
289
290     unsigned char tlv1_value[] = {
291            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
292     MIHGenericTLVParser tlv1 ( tlvListContainer.push_back_space());
293     tlv1.type() = 0x42;
294     tlv1.value( tlv1_value);
295
296     unsigned char tlv2_value[] = {
297             0x1a, 0x2b, 0x3c, 0x4d };
298     MIHGenericTLVParser tlv2 ( tlvListContainer.push_back_space());
299     tlv2.type() = 0x43;
300     tlv2.value( tlv2_value);
301
302     mihPacket.finalizeAll();
303
304     unsigned char data[] = {
305             // MIH header
306             0x10, 0x54, 0x00, 0x00, 0x00, 0x15,
307             // variable payload length:
308             0x00, 0x2b,
309             // source MIHF_ID TLV:
310             0x01, 0x10, // type, length
311             0x0f,  // value-length
312             0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c,
313             0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65,  // value
314             // destination MIHF_ID TLV:
315             0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74,
316             // MIH Payload (two test tlvs)
317             // first test tlv
318             0x42, // type
319             0x0a, // first bit not set, length=10
320             0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, // value
321             // second test tlv
322             0x43, // type
323             0x04, // first bit not set, length=4
324             0x1a, 0x2b, 0x3c, 0x4d // value
325     };
326     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
327             mihPacket.data().begin(), mihPacket.data().end() );
328 }
329
330 SENF_AUTO_UNIT_TEST(Test_MIHFIdTLV)
331 {
332     unsigned char data[] = {
333             // MIH header
334             0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x06,
335             // source MIHF_ID TLV:
336             0x01, 0x01, // type, length
337             0x00,       // value-length
338             // destination MIHF_ID TLV:
339             0x02, 0x01, // type, length
340             0x00        // value-length
341     };
342
343     MIHPacket mihPacket (MIHPacket::create(data));
344     BOOST_CHECK( mihPacket->src_mihfId().valueEquals( MIHFId::Multicast) );
345     BOOST_CHECK( mihPacket->dst_mihfId().valueEquals( MIHFId::Multicast) );
346 }
347
348 ///////////////////////////////cc.e////////////////////////////////////////
349 #undef prefix_
350
351 \f
352 // Local Variables:
353 // mode: c++
354 // fill-column: 100
355 // c-file-style: "senf"
356 // indent-tabs-mode: nil
357 // ispell-local-dictionary: "american"
358 // compile-command: "scons -u test"
359 // comment-column: 40
360 // End: