switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / DefaultBundle / ICMPv6Packet.test.cc
1 // $Id$
2 //
3 // Copyright (C) 2008
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 //   Philipp Batroff <pug@berlios.de>
27
28 /** \file
29     \brief ICMPv6Packet unit tests */
30
31 // Custom includes
32 #include <sstream>
33 #include "ICMPv6Packet.hh"
34 #include "ICMPv6TypePacket.hh"
35 #include "NDPOptions.hh"
36
37 #include <senf/Utils/auto_unit_test.hh>
38 #include <boost/test/test_tools.hpp>
39
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41
42 SENF_AUTO_UNIT_TEST(ICMPv6Packet_packet)
43 {
44     unsigned char dataListenerReport[] = {
45             0x8f, 0x00, 0x8d, 0x54, 0x00, 0x00, 0x00, 0x01,
46             0x04, 0x00, 0x00, 0x00, 0xff, 0x15, 0x00, 0x00,
47             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48             0x00, 0x00, 0x00, 0x16
49     };
50
51     senf::ICMPv6Packet pListenerReport ( senf::ICMPv6Packet::create(dataListenerReport) );
52
53     BOOST_CHECK_EQUAL( pListenerReport->type(),     0x8f   );
54     BOOST_CHECK_EQUAL( pListenerReport->code(),     0x00   );
55     BOOST_CHECK_EQUAL( pListenerReport->checksum(), 0x8d54 );
56     BOOST_CHECK( pListenerReport.next() );
57     BOOST_CHECK( pListenerReport.next().is<senf::MLDv2ListenerReport>() );
58     BOOST_CHECK_EQUAL( pListenerReport.next().size(), 24u );
59
60     std::ostringstream oss (std::ostringstream::out);
61     SENF_CHECK_NO_THROW( pListenerReport.dump( oss));
62
63     unsigned char dataListenerQuery[] = {
64         0x82, 0x00, 0xf7, 0xd6, 0x27, 0x10, 0x00, 0x00,
65         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67         0x02, 0x7d, 0x00, 0x00
68     };
69     senf::ICMPv6Packet pListenerQuery ( senf::ICMPv6Packet::create(dataListenerQuery) );
70     BOOST_CHECK_EQUAL( pListenerQuery->type(),     0x82   );
71     BOOST_CHECK_EQUAL( pListenerQuery->code(),     0x00   );
72     BOOST_CHECK_EQUAL( pListenerQuery->checksum(), 0xf7d6 );
73     BOOST_CHECK( pListenerQuery.next() );
74     BOOST_CHECK( pListenerQuery.next().is<senf::MLDv2ListenerQuery>() );
75     BOOST_CHECK_EQUAL( pListenerQuery.next().size(), 24u );
76
77     SENF_CHECK_NO_THROW( pListenerQuery.dump( oss));
78
79     unsigned char dataEchoRequest[] = {
80         0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07
81     };
82     senf::ICMPv6Packet pEchoRequest ( senf::ICMPv6Packet::create(dataEchoRequest) );
83     BOOST_CHECK_EQUAL( pEchoRequest->type(),     0x80   );
84     BOOST_CHECK_EQUAL( pEchoRequest->code(),     0x00   );
85     BOOST_CHECK_EQUAL( pEchoRequest->checksum(), 0x0000 );
86     BOOST_CHECK( pEchoRequest.next() );
87     BOOST_CHECK( pEchoRequest.next().is<senf::ICMPv6EchoRequest>() );
88     BOOST_CHECK_EQUAL( pEchoRequest.next().size(), 4u );
89
90     SENF_CHECK_NO_THROW( pEchoRequest.dump( oss));
91
92     unsigned char dataEchoReply[] = {
93         0x81, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x4d
94     };
95
96     senf::ICMPv6Packet pEchoReply ( senf::ICMPv6Packet::create(dataEchoReply) );
97     BOOST_CHECK_EQUAL( pEchoReply->type(),     0x81   );
98     BOOST_CHECK_EQUAL( pEchoReply->code(),     0x00   );
99     BOOST_CHECK_EQUAL( pEchoReply->checksum(), 0x0000 );
100     BOOST_CHECK( pEchoReply.next() );
101     BOOST_CHECK( pEchoReply.next().is<senf::ICMPv6EchoReply>() );
102     BOOST_CHECK_EQUAL( pEchoReply.next().size(), 4u );
103
104     SENF_CHECK_NO_THROW( pEchoReply.dump( oss));
105
106
107     unsigned char dataErrDestUnreachable[] = {
108         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
109     };
110
111     senf::ICMPv6Packet pErrDestUnreachable ( senf::ICMPv6Packet::create(dataErrDestUnreachable) );
112     BOOST_CHECK_EQUAL( pErrDestUnreachable->type(),     0x01   );
113     BOOST_CHECK_EQUAL( pErrDestUnreachable->code(),     0x00   );
114     BOOST_CHECK_EQUAL( pErrDestUnreachable->checksum(), 0x0000 );
115     BOOST_CHECK( pErrDestUnreachable.next() );
116     BOOST_CHECK( pErrDestUnreachable.next().is<senf::ICMPv6ErrDestUnreachable>() );
117     BOOST_CHECK_EQUAL( pErrDestUnreachable.next().size(), 4u );
118
119     SENF_CHECK_NO_THROW( pErrDestUnreachable.dump( oss));
120
121
122     unsigned char dataErrTooBig[] = {
123         0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xd8
124     };
125
126     senf::ICMPv6Packet pErrTooBig ( senf::ICMPv6Packet::create(dataErrTooBig) );
127     BOOST_CHECK_EQUAL( pErrTooBig->type(),     0x02   );
128     BOOST_CHECK_EQUAL( pErrTooBig->code(),     0x00   );
129     BOOST_CHECK_EQUAL( pErrTooBig->checksum(), 0x0000 );
130     BOOST_CHECK( pErrTooBig.next() );
131     BOOST_CHECK( pErrTooBig.next().is<senf::ICMPv6ErrTooBig>() );
132     BOOST_CHECK_EQUAL( pErrTooBig.next().size(), 4u );
133
134     SENF_CHECK_NO_THROW( pErrTooBig.dump( oss));
135
136
137     unsigned char dataErrTimeExceeded[] = {
138         0x03, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
139     };
140
141     senf::ICMPv6Packet pErrTimeExceeded ( senf::ICMPv6Packet::create(dataErrTimeExceeded) );
142     BOOST_CHECK_EQUAL( pErrTimeExceeded->type(),     0x03   );
143     BOOST_CHECK_EQUAL( pErrTimeExceeded->code(),     0x63   );
144     BOOST_CHECK_EQUAL( pErrTimeExceeded->checksum(), 0x0000 );
145     BOOST_CHECK( pErrTimeExceeded.next() );
146     BOOST_CHECK( pErrTimeExceeded.next().is<senf::ICMPv6ErrTimeExceeded>() );
147     BOOST_CHECK_EQUAL( pErrTimeExceeded.next().size(), 4u );
148
149     SENF_CHECK_NO_THROW( pErrTimeExceeded.dump( oss));
150
151
152     unsigned char dataErrParamProblem[] = {
153         0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
154     };
155
156     senf::ICMPv6Packet pErrParamProblem ( senf::ICMPv6Packet::create(dataErrParamProblem) );
157     BOOST_CHECK_EQUAL( pErrParamProblem->type(),     0x04   );
158     BOOST_CHECK_EQUAL( pErrParamProblem->code(),     0x01   );
159     BOOST_CHECK_EQUAL( pErrParamProblem->checksum(), 0x0000 );
160     BOOST_CHECK( pErrParamProblem.next() );
161     BOOST_CHECK( pErrParamProblem.next().is<senf::ICMPv6ErrParamProblem>() );
162     BOOST_CHECK_EQUAL( pErrParamProblem.next().size(), 4u );
163
164     SENF_CHECK_NO_THROW( pErrParamProblem.dump( oss));
165
166     unsigned char dataRouterSolicitation[] = {
167         0x85, 0x00, 0x00, 0x00,
168         0x00, 0x00, 0x00, 0x00,
169         0x05, 0x01, 0x00, 0x00,
170         0x12, 0x34, 0x56, 0x78
171     };
172
173     senf::ICMPv6Packet pRouterSolicitation ( senf::ICMPv6Packet::create(dataRouterSolicitation) );
174     BOOST_CHECK_EQUAL( pRouterSolicitation->type(),     0x85   );
175     BOOST_CHECK_EQUAL( pRouterSolicitation->code(),     0x00   );
176     BOOST_CHECK_EQUAL( pRouterSolicitation->checksum(), 0x0000 );
177     BOOST_CHECK( pRouterSolicitation.next() );
178     BOOST_CHECK( pRouterSolicitation.next().is<senf::NDPRouterSolicitationMessage>() );
179     BOOST_CHECK_EQUAL( pRouterSolicitation.next().size(), 12u );
180
181     senf::NDPRouterSolicitationMessage pOption(pRouterSolicitation.next().as<senf::NDPRouterSolicitationMessage>());
182     senf::NDPRouterSolicitationMessage::Parser::options_t::container optC(pOption->options() );
183     senf::NDPRouterSolicitationMessage::Parser::options_t::container::iterator listIter (optC.begin());
184     BOOST_CHECK_EQUAL(listIter->type(),5u);
185     BOOST_CHECK_EQUAL(listIter->length(),1u);
186
187     SENF_CHECK_NO_THROW( pRouterSolicitation.dump( oss));
188
189     unsigned char dataRouterAdvertisement[] = {
190         0x86, 0x00, 0x00, 0x00,
191         0xFF, 0x00, 0x23, 0x28,
192         0x00, 0x00, 0x00, 0x00,
193         0x00, 0x00, 0x00, 0x00,
194     };
195
196     senf::ICMPv6Packet pRouterAdvertisement ( senf::ICMPv6Packet::create(dataRouterAdvertisement) );
197     BOOST_CHECK_EQUAL( pRouterAdvertisement->type(),     0x86   );
198     BOOST_CHECK_EQUAL( pRouterAdvertisement->code(),     0x00   );
199     BOOST_CHECK_EQUAL( pRouterAdvertisement->checksum(), 0x0000 );
200     BOOST_CHECK( pRouterAdvertisement.next() );
201     BOOST_CHECK( pRouterAdvertisement.next().is<senf::NDPRouterAdvertisementMessage>() );
202     BOOST_CHECK_EQUAL( pRouterAdvertisement.next().size(), 12u );
203
204     SENF_CHECK_NO_THROW( pRouterAdvertisement.dump( oss));
205
206     unsigned char dataNeighborSolicitation[] = {
207         0x87, 0x00, 0x00, 0x00,
208         0x00, 0x00, 0x00, 0x00,
209         0x00, 0x00, 0x00, 0x00,
210         0x00, 0x00, 0x00, 0x00,
211         0x00, 0x00, 0x00, 0x00,
212         0x00, 0x00, 0x00, 0x00
213     };
214
215     senf::ICMPv6Packet pNeighborSolicitation ( senf::ICMPv6Packet::create(dataNeighborSolicitation) );
216     BOOST_CHECK_EQUAL( pNeighborSolicitation->type(),     0x87   );
217     BOOST_CHECK_EQUAL( pNeighborSolicitation->code(),     0x00   );
218     BOOST_CHECK_EQUAL( pNeighborSolicitation->checksum(), 0x0000 );
219     BOOST_CHECK( pNeighborSolicitation.next() );
220     BOOST_CHECK( pNeighborSolicitation.next().is<senf::NDPNeighborSolicitationMessage>() );
221     BOOST_CHECK_EQUAL( pNeighborSolicitation.next().size(), 20u );
222
223     SENF_CHECK_NO_THROW( pNeighborSolicitation.dump( oss));
224
225     unsigned char dataNeighborAdvertisement[] = {
226         0x88, 0x00, 0x00, 0x00,
227         0x00, 0x00, 0x00, 0x00,
228         0x00, 0x00, 0x00, 0x00,
229         0x00, 0x00, 0x00, 0x00,
230         0x00, 0x00, 0x00, 0x00,
231         0x00, 0x00, 0x00, 0x00
232     };
233
234     senf::ICMPv6Packet pNeighborAdvertisement ( senf::ICMPv6Packet::create(dataNeighborAdvertisement) );
235     BOOST_CHECK_EQUAL( pNeighborAdvertisement->type(),     0x88   );
236     BOOST_CHECK_EQUAL( pNeighborAdvertisement->code(),     0x00   );
237     BOOST_CHECK_EQUAL( pNeighborAdvertisement->checksum(), 0x0000 );
238     BOOST_CHECK( pNeighborAdvertisement.next() );
239     BOOST_CHECK( pNeighborAdvertisement.next().is<senf::NDPNeighborAdvertisementMessage>() );
240     BOOST_CHECK_EQUAL( pNeighborAdvertisement.next().size(), 20u );
241
242     SENF_CHECK_NO_THROW( pNeighborAdvertisement.dump( oss));
243
244     unsigned char dataRedirect[] = {
245         0x89, 0x00, 0x00, 0x00,
246         0x00, 0x00, 0x00, 0x00,
247         0x00, 0x00, 0x00, 0x00,
248         0x00, 0x00, 0x00, 0x00,
249         0x00, 0x00, 0x00, 0x00,
250         0x00, 0x00, 0x00, 0x00,
251         0x00, 0x00, 0x00, 0x00,
252         0x00, 0x00, 0x00, 0x00,
253         0x00, 0x00, 0x00, 0x00,
254         0x00, 0x00, 0x00, 0x00
255     };
256
257     senf::ICMPv6Packet pRedirect ( senf::ICMPv6Packet::create(dataRedirect) );
258     BOOST_CHECK_EQUAL( pRedirect->type(),     0x89   );
259     BOOST_CHECK_EQUAL( pRedirect->code(),     0x00   );
260     BOOST_CHECK_EQUAL( pRedirect->checksum(), 0x0000 );
261     BOOST_CHECK( pRedirect.next() );
262     BOOST_CHECK( pRedirect.next().is<senf::NDPRedirectMessage>() );
263     BOOST_CHECK_EQUAL( pRedirect.next().size(), 36u );
264
265     SENF_CHECK_NO_THROW( pRedirect.dump( oss));
266 }
267
268 SENF_AUTO_UNIT_TEST(ICMPv6Packet_create)
269 {
270     std::ostringstream oss (std::ostringstream::out);
271
272     unsigned char ping[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3a, 0x40,
273                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
275                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
277                              0x80, 0x00, 0xda, 0xe0, 0x9f, 0x7e, 0x00, 0x09,
278
279                              0xb7, 0x3c, 0xbb, 0x4a, 0x9d, 0x90, 0x0a, 0x00, //payload
280                              0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
281                              0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
282                              0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
283                              0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
284                              0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
285                              0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
286     };
287
288     senf::IPv6Packet ip (senf::IPv6Packet::create());
289     ip->hopLimit() = 64;
290     ip->source() = senf::INet6Address::Loopback;
291     ip->destination() = senf::INet6Address::Loopback;
292
293     senf::ICMPv6Packet icmp (senf::ICMPv6Packet::createAfter(ip));
294     icmp->code() = 0;
295
296     senf::ICMPv6EchoRequest ereq (senf::ICMPv6EchoRequest::createAfter(icmp));
297     ereq->identifier() = 0x9f7e;
298     ereq->seqNr() = 9;
299
300     senf::DataPacket data (
301         senf::DataPacket::createAfter(ereq, std::make_pair(ping+48, ping+sizeof(ping))));
302
303     ip.finalizeAll();
304
305     SENF_CHECK_NO_THROW (ip.dump( oss ));
306
307     std::string dump (
308         "Internet protocol Version 6:\n"
309         "  version                 : 6\n"
310         "  traffic class           : 0x00\n"
311         "  flow label              : 0x00000\n"
312         "  payload length          : 64\n"
313         "  next header             : 58\n"
314         "  hop limit               : 64\n"
315         "  source                  : ::1\n"
316         "  destination             : ::1\n"
317         "ICMPv6 protocol:\n"
318         "  type                    : 128\n"
319         "  code                    : 0\n"
320         "  checksum                : 0xdae0\n"
321         "ICMPv6 Echo Request:\n"
322         "  Identifier              : 40830\n"
323         "  SequenceNumber          : 9\n"
324         "Payload data (56 bytes)\n"
325         );
326
327     {
328         std::stringstream ss;
329         ip.dump(ss);
330         BOOST_CHECK_EQUAL( ss.str(), dump );
331     }
332
333     SENF_CHECK_EQUAL_COLLECTIONS( ip.data().begin(), ip.data().end(),
334                                   ping, ping+sizeof(ping) );
335
336     senf::IPv6Packet orig (senf::IPv6Packet::create(ping));
337
338     {
339         std::stringstream ss;
340         orig.dump(ss);
341         BOOST_CHECK_EQUAL( ss.str(), dump );
342     }
343 }
344
345 //-/////////////////////////////////////////////////////////////////////////////////////////////////
346
347 \f
348 // Local Variables:
349 // mode: c++
350 // fill-column: 100
351 // c-file-style: "senf"
352 // indent-tabs-mode: nil
353 // ispell-local-dictionary: "american"
354 // compile-command: "scons -u test"
355 // comment-column: 40
356 // End: