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