iface_mgr_unittest.cc 105 KB
Newer Older
1
// Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC")
2
3
4
5
6
7
8
9
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11
12
13
14
15
16
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#include <config.h>

17
18
19
#include <asiolink/io_address.h>
#include <dhcp/dhcp4.h>
#include <dhcp/iface_mgr.h>
20
#include <dhcp/option.h>
21
#include <dhcp/pkt6.h>
22
#include <dhcp/pkt_filter.h>
23
#include <dhcp/tests/iface_mgr_test_config.h>
24
#include <dhcp/tests/pkt_filter6_test_utils.h>
25

26
#include <boost/bind.hpp>
27
#include <boost/scoped_ptr.hpp>
28
29
#include <gtest/gtest.h>

30
31
32
33
34
35
#include <fstream>
#include <iostream>
#include <sstream>

#include <arpa/inet.h>
#include <unistd.h>
36
37
38

using namespace std;
using namespace isc;
39
using namespace isc::asiolink;
40
using namespace isc::dhcp;
41
using namespace isc::dhcp::test;
42
using boost::scoped_ptr;
43

44
namespace {
45

46
47
48
49
50
51
52
53
// Name of loopback interface detection
const size_t BUF_SIZE = 32;
char LOOPBACK[BUF_SIZE] = "lo";

// Ports used during testing
const uint16_t PORT1 = 10547;   // V6 socket
const uint16_t PORT2 = 10548;   // V4 socket

54
55
56
57
// On some systems measured duration of receive6() and receive4() appears to be
// shorter than select() timeout.  This may be the case if different time
// resolutions are used by these functions.  For such cases we set the
// tolerance to 0.01s.
58
59
const uint32_t TIMEOUT_TOLERANCE = 10000;

60
61
62
63
64
65
66
67
/// This test verifies that the socket read buffer can be used to
/// receive the data and that the data can be read from it.
TEST(IfaceTest, readBuffer) {
    // Create fake interface object.
    Iface iface("em0", 0);
    // The size of read buffer should initially be 0 and the returned
    // pointer should be NULL.
    ASSERT_EQ(0, iface.getReadBufferSize());
68
    EXPECT_EQ(NULL, iface.getReadBuffer());
69
70
71
72
73
74

    // Let's resize the buffer.
    iface.resizeReadBuffer(256);
    // Check that the buffer has expected size.
    ASSERT_EQ(256, iface.getReadBufferSize());
    // The returned pointer should now be non-NULL.
75
    uint8_t* buf_ptr = iface.getReadBuffer();
76
77
78
79
80
81
82
    ASSERT_FALSE(buf_ptr == NULL);

    // Use the pointer to set some data.
    for (int i = 0; i < iface.getReadBufferSize(); ++i) {
        buf_ptr[i] = i;
    }

83
    // Get the pointer again and validate the data.
84
    buf_ptr = iface.getReadBuffer();
85
86
    ASSERT_EQ(256, iface.getReadBufferSize());
    for (int i = 0; i < iface.getReadBufferSize(); ++i) {
87
88
        // Use assert so as it fails on the first failure, no need
        // to continue further checks.
89
        ASSERT_EQ(i, buf_ptr[i]);
90
91
92
    }
}

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/// Mock object implementing PktFilter class.  It is used by
/// IfaceMgrTest::setPacketFilter to verify that IfaceMgr::setPacketFilter
/// sets this object as a handler for opening sockets. This dummy
/// class simply records that openSocket function was called by
/// the IfaceMgr as expected.
///
/// @todo This class currently doesn't verify that send/receive functions
/// were called. In order to test it, there is a need to supply dummy
/// function performing select() on certain sockets. The system select()
/// call will fail when dummy socket descriptor is provided and thus
/// TestPktFilter::receive will never be called. The appropriate extension
/// to IfaceMgr is planned along with implementation of other "Packet
/// Filters" such as these supporting Linux Packet Filtering and
/// Berkley Packet Filtering.
class TestPktFilter : public PktFilter {
public:

    /// Constructor
    TestPktFilter()
        : open_socket_called_(false) {
    }

115
116
117
118
    virtual bool isDirectResponseSupported() const {
        return (false);
    }

119
120
121
122
123
124
125
126
127
128
129
130
131
132
    /// @brief Pretend to open a socket.
    ///
    /// This function doesn't open a real socket. It always returns the
    /// same fake socket descriptor. It also records the fact that it has
    /// been called in the public open_socket_called_ member.
    /// As in the case of opening a real socket, this function will check
    /// if there is another fake socket "bound" to the same address and port.
    /// If there is, it will throw an exception. This allows to simulate the
    /// conditions when one of the sockets can't be open because there is
    /// a socket already open and test how IfaceMgr will handle it.
    ///
    /// @param iface An interface on which the socket is to be opened.
    /// @param addr An address to which the socket is to be bound.
    /// @param port A port to which the socket is to be bound.
133
    virtual SocketInfo openSocket(Iface& iface,
134
135
                                  const isc::asiolink::IOAddress& addr,
                                  const uint16_t port,
136
                                  const bool join_multicast,
137
                                  const bool) {
138
139
140
141
142
        // Check if there is any other socket bound to the specified address
        // and port on this interface.
        const Iface::SocketCollection& sockets = iface.getSockets();
        for (Iface::SocketCollection::const_iterator socket = sockets.begin();
             socket != sockets.end(); ++socket) {
143
144
145
            if (((socket->addr_ == addr) ||
                 ((socket->addr_ == IOAddress("::")) && join_multicast)) &&
                socket->port_ == port) {
146
147
148
                isc_throw(SocketConfigError, "test socket bind error");
            }
        }
149
        open_socket_called_ = true;
150
        return (SocketInfo(addr, port, 255));
151
152
153
154
155
156
157
158
159
    }

    /// Does nothing
    virtual Pkt4Ptr receive(const Iface&,
                            const SocketInfo&) {
        return (Pkt4Ptr());
    }

    /// Does nothing
160
    virtual int send(const Iface&, uint16_t, const Pkt4Ptr&) {
161
162
163
164
165
166
167
        return (0);
    }

    /// Holds the information whether openSocket was called on this
    /// object after its creation.
    bool open_socket_called_;
};
168

169
class NakedIfaceMgr: public IfaceMgr {
170
    // "Naked" Interface Manager, exposes internal fields
171
public:
172
173

    /// @brief Constructor.
174
    NakedIfaceMgr() {
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
        loDetect();
    }

    /// @brief detects name of the loopback interface
    ///
    /// This method detects name of the loopback interface.
    static void loDetect() {
        // Poor man's interface detection.  It will go away as soon as proper
        // interface detection is implemented
        if (if_nametoindex("lo") > 0) {
            snprintf(LOOPBACK, BUF_SIZE - 1, "lo");
        } else if (if_nametoindex("lo0") > 0) {
            snprintf(LOOPBACK, BUF_SIZE - 1, "lo0");
        } else {
            cout << "Failed to detect loopback interface. Neither "
                 << "lo nor lo0 worked. I give up." << endl;
            FAIL();
        }
193
    }
194
195
196
197

    /// @brief Returns the collection of existing interfaces.
    IfaceCollection& getIfacesLst() { return (ifaces_); }

198
    /// @brief This function creates fictitious interfaces with fictious
199
200
201
202
203
204
205
206
207
208
209
    /// addresses.
    ///
    /// These interfaces can be used in tests that don't actually try
    /// to open the sockets on these interfaces. Some tests use mock
    /// objects to mimic sockets being open. These interfaces are
    /// suitable for such tests.
    void createIfaces() {

        ifaces_.clear();

        // local loopback
210
211
212
213
        Iface lo = createIface("lo", 0);
        lo.addAddress(IOAddress("127.0.0.1"));
        lo.addAddress(IOAddress("::1"));
        ifaces_.push_back(lo);
214
        // eth0
215
216
217
218
219
        Iface eth0 = createIface("eth0", 1);
        eth0.addAddress(IOAddress("10.0.0.1"));
        eth0.addAddress(IOAddress("fe80::3a60:77ff:fed5:cdef"));
        eth0.addAddress(IOAddress("2001:db8:1::1"));
        ifaces_.push_back(eth0);
220
        // eth1
221
222
223
224
        Iface eth1 = createIface("eth1", 2);
        eth1.addAddress(IOAddress("192.0.2.3"));
        eth1.addAddress(IOAddress("fe80::3a60:77ff:fed5:abcd"));
        ifaces_.push_back(eth1);
225
226
227
228
229
230
231
232
233
234
    }

    /// @brief Create an object representing interface.
    ///
    /// Apart from creating an interface, this function also sets the
    /// interface flags:
    /// - loopback flag if interface name is "lo"
    /// - up always true
    /// - running always true
    /// - inactive always to false
235
    /// - multicast always to true
236
    /// - broadcast always to false
237
238
239
240
241
242
243
244
    ///
    /// If one needs to modify the default flag settings, the setIfaceFlags
    /// function should be used.
    ///
    /// @param name A name of the interface to be created.
    /// @param ifindex An index of the interface to be created.
    ///
    /// @return An object representing interface.
245
    static Iface createIface(const std::string& name, const int ifindex) {
246
247
248
        Iface iface(name, ifindex);
        if (name == "lo") {
            iface.flag_loopback_ = true;
249
250
251
252
253
254
            // Don't open sockets on loopback interface.
            iface.inactive4_ = true;
            iface.inactive6_ = true;
        } else {
            iface.inactive4_ = false;
            iface.inactive6_ = false;
255
        }
256
        iface.flag_multicast_ = true;
257
258
259
260
261
262
        // On BSD systems, the SO_BINDTODEVICE option is not supported.
        // Therefore the IfaceMgr will throw an exception on attempt to
        // open sockets on more than one broadcast-capable interface at
        // the same time. In order to prevent this error, we mark all
        // interfaces broadcast-incapable for unit testing.
        iface.flag_broadcast_ = false;
263
264
265
266
267
        iface.flag_up_ = true;
        iface.flag_running_ = true;
        return (iface);
    }

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
    /// @brief Checks if the specified interface has a socket bound to a
    /// specified adddress.
    ///
    /// @param iface_name A name of the interface.
    /// @param addr An address to be checked for binding.
    ///
    /// @return true if there is a socket bound to the specified address.
    bool isBound(const std::string& iface_name, const std::string& addr) {
        Iface* iface = getIface(iface_name);
        if (iface == NULL) {
            ADD_FAILURE() << "the interface " << iface_name << " doesn't exist";
            return (false);
        }
        const Iface::SocketCollection& sockets = iface->getSockets();
        for (Iface::SocketCollection::const_iterator sock = sockets.begin();
             sock != sockets.end(); ++sock) {
            if (sock->addr_ == IOAddress(addr)) {
                return (true);
286
287
288
289
290
291
292
293
294
295
            } else if ((sock->addr_ == IOAddress("::")) &&
                       (IOAddress(addr).isV6LinkLocal())) {
                for (Iface::AddressCollection::const_iterator addr_it =
                         iface->getAddresses().begin();
                     addr_it != iface->getAddresses().end();
                     ++addr_it) {
                    if (*addr_it == IOAddress(addr)) {
                        return (true);
                    }
                }
296
297
298
299
300
301
            }
        }
        return (false);
    }

    /// @brief Modify flags on the interface.
302
303
304
305
306
307
308
309
    ///
    /// @param name A name of the interface.
    /// @param loopback A new value of the loopback flag.
    /// @param up A new value of the up flag.
    /// @param running A new value of the running flag.
    /// @param inactive A new value of the inactive flag.
    void setIfaceFlags(const std::string& name, const bool loopback,
                       const bool up, const bool running,
310
311
                       const bool inactive4,
                       const bool inactive6) {
312
313
314
315
316
317
        for (IfaceMgr::IfaceCollection::iterator iface = ifaces_.begin();
             iface != ifaces_.end(); ++iface) {
            if (iface->getName() == name) {
                iface->flag_loopback_ = loopback;
                iface->flag_up_ = up;
                iface->flag_running_ = running;
318
319
                iface->inactive4_ = inactive4;
                iface->inactive6_ = inactive6;
320
321
322
            }
        }
    }
323

324
325
};

326
327
328
329
330
331
332
/// @brief A test fixture class for IfaceMgr.
///
/// @todo Sockets being opened by IfaceMgr tests should be managed by
/// the test fixture. In particular, the class should close sockets after
/// each test. Current approach where test cases are responsible for
/// closing sockets is resource leak prone, especially in case of the
/// test failure path.
333
334
class IfaceMgrTest : public ::testing::Test {
public:
335
336
337
    /// @brief Constructor.
    IfaceMgrTest()
        : errors_count_(0) {
338
    }
339

340
341
    ~IfaceMgrTest() {
    }
342

343
344
345
346
347
348
349
350
351
352
    /// @brief Tests the number of IPv6 sockets on interface
    ///
    /// This function checks the expected number of open IPv6 sockets on the
    /// specified interface. On non-Linux systems, sockets are bound to a
    /// link-local address and the number of unicast addresses specified.
    /// On Linux systems, there is one more socket bound to a ff02::1:2
    /// multicast address.
    ///
    /// @param iface An interface on which sockets are open.
    /// @param unicast_num A number of unicast addresses bound.
353
354
355
    /// @param link_local_num A number of link local addresses bound.
    void checkSocketsCount6(const Iface& iface, const int unicast_num,
                            const int link_local_num = 1) {
356
357
358
359
360
361
362
363
        // On local-loopback interface, there should be no sockets.
        if (iface.flag_loopback_) {
            ASSERT_TRUE(iface.getSockets().empty())
                << "expected empty socket set on loopback interface "
                << iface.getName();
            return;
        }
#if defined OS_LINUX
364
365
366
367
368
        // On Linux, for each link-local address there may be an
        // additional socket opened and bound to ff02::1:2. This socket
        // is only opened if the interface is multicast-capable.
        ASSERT_EQ(unicast_num + (iface.flag_multicast_ ? link_local_num : 0)
                  + link_local_num, iface.getSockets().size())
369
370
371
372
            << "invalid number of sockets on interface "
            << iface.getName();
#else
        // On non-Linux, there is no additional socket.
373
        ASSERT_EQ(unicast_num + link_local_num, iface.getSockets().size())
374
375
376
377
378
379
            << "invalid number of sockets on interface "
            << iface.getName();

#endif
    }

380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
    // Get ther number of IPv4 or IPv6 sockets on the loopback interface
    int getOpenSocketsCount(const Iface& iface, uint16_t family) const {
        // Get all sockets.
        Iface::SocketCollection sockets = iface.getSockets();

        // Loop through sockets and try to find the ones which match the
        // specified type.
        int sockets_count = 0;
        for (Iface::SocketCollection::const_iterator sock = sockets.begin();
             sock != sockets.end(); ++sock) {
            // Match found, increase the counter.
            if (sock->family_ == family) {
                ++sockets_count;
            }
        }
        return (sockets_count);
    }

398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
    /// @brief returns socket bound to a specific address (or NULL)
    ///
    /// A helper function, used to pick a socketinfo that is bound to a given
    /// address.
    ///
    /// @param sockets sockets collection
    /// @param addr address the socket is bound to
    ///
    /// @return socket info structure (or NULL)
    const isc::dhcp::SocketInfo*
    getSocketByAddr(const isc::dhcp::Iface::SocketCollection& sockets,
                    const IOAddress& addr) {
        for (isc::dhcp::Iface::SocketCollection::const_iterator s =
                 sockets.begin(); s != sockets.end(); ++s) {
            if (s->addr_ == addr) {
                return (&(*s));
            }
        }
        return (NULL);
    }

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
    /// @brief Implements an IfaceMgr error handler.
    ///
    /// This function can be installed as an error handler for the
    /// IfaceMgr::openSockets4 function. The error handler is invoked
    /// when an attempt to open a particular socket fails for any reason.
    /// Typically, the error handler will log a warning. When the error
    /// handler returns, the openSockets4 function should continue opening
    /// sockets on other interfaces.
    ///
    /// @param errmsg An error string indicating the reason for failure.
    void ifaceMgrErrorHandler(const std::string&) {
        // Increase the counter of invocations to this function. By checking
        // this number, a test amy check if the expected number of errors
        // has occurred.
        ++errors_count_;
    }

    /// Holds the invocation counter for ifaceMgrErrorHandler.
    int errors_count_;

439
440
};

441
442
443
// We need some known interface to work reliably. Loopback interface is named
// lo on Linux and lo0 on BSD boxes. We need to find out which is available.
// This is not a real test, but rather a workaround that will go away when
444
// interface detection is implemented on all OSes.
445
TEST_F(IfaceMgrTest, loDetect) {
446
    NakedIfaceMgr::loDetect();
447
448
}

449
// Uncomment this test to create packet writer. It will
450
451
452
453
454
455
456
457
// write incoming DHCPv6 packets as C arrays. That is useful
// for generating test sequences based on actual traffic
//
// TODO: this potentially should be moved to a separate tool
//

#if 0
TEST_F(IfaceMgrTest, dhcp6Sniffer) {
458
    // Testing socket operation in a portable way is tricky
459
460
461
462
463
464
465
466
    // without interface detection implemented

    unlink("interfaces.txt");

    ofstream interfaces("interfaces.txt", ios::ate);
    interfaces << "eth0 fe80::21e:8cff:fe9b:7349";
    interfaces.close();

467
    boost::scoped_ptr<NakedIfaceMgr> ifacemgr = new NakedIfaceMgr();
468

469
    Pkt6Ptr pkt;
470
471
472
    int cnt = 0;
    cout << "---8X-----------------------------------------" << endl;
    while (true) {
473
        pkt.reset(ifacemgr->receive());
474

475
        cout << "// this code is autogenerated. Do NOT edit." << endl;
476
477
478
479
480
        cout << "// Received " << pkt->data_len_ << " bytes packet:" << endl;
        cout << "Pkt6 *capture" << cnt++ << "() {" << endl;
        cout << "    Pkt6* pkt;" << endl;
        cout << "    pkt = new Pkt6(" << pkt->data_len_ << ");" << endl;
        cout << "    pkt->remote_port_ = " << pkt-> remote_port_ << ";" << endl;
481
        cout << "    pkt->remote_addr_ = IOAddress(\""
482
             << pkt->remote_addr_ << "\");" << endl;
483
        cout << "    pkt->local_port_ = " << pkt-> local_port_ << ";" << endl;
484
        cout << "    pkt->local_addr_ = IOAddress(\""
485
             << pkt->local_addr_ << "\");" << endl;
486
487
        cout << "    pkt->ifindex_ = " << pkt->ifindex_ << ";" << endl;
        cout << "    pkt->iface_ = \"" << pkt->iface_ << "\";" << endl;
488

489
490
        // TODO it is better to declare statically initialize the array
        // and then memcpy it to packet.
491
        for (int i=0; i< pkt->data_len_; i++) {
492
493
            cout << "    pkt->data_[" << i << "]="
                 << (int)(unsigned char)pkt->data_[i] << "; ";
494
495
496
497
498
499
500
            if (!(i%4))
                cout << endl;
        }
        cout << endl;
        cout << "    return (pkt);" << endl;
        cout << "}" << endl << endl;

501
        pkt.reset();
502
503
    }
    cout << "---8X-----------------------------------------" << endl;
504

505
    // Never happens. Infinite loop is infinite
506
507
508
}
#endif

509
TEST_F(IfaceMgrTest, basic) {
510
    // Checks that IfaceManager can be instantiated
511
512
513
514
515

    IfaceMgr & ifacemgr = IfaceMgr::instance();
    ASSERT_TRUE(&ifacemgr != 0);
}

516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575

// This test verifies that sockets can be closed selectively, i.e. all
// IPv4 sockets can be closed first and all IPv6 sockets remain open.
TEST_F(IfaceMgrTest, closeSockets) {
    // Will be using local loopback addresses for this test.
    IOAddress loaddr("127.0.0.1");
    IOAddress loaddr6("::1");

    // Create instance of IfaceMgr.
    boost::scoped_ptr<NakedIfaceMgr> iface_mgr(new NakedIfaceMgr());
    ASSERT_TRUE(iface_mgr);

    // Out constructor does not detect interfaces by itself. We need
    // to create one and add.
    int ifindex = if_nametoindex(LOOPBACK);
    ASSERT_GT(ifindex, 0);
    Iface lo_iface(LOOPBACK, ifindex);
    iface_mgr->getIfacesLst().push_back(lo_iface);

    // Create set of V4 and V6 sockets on the loopback interface.
    // They must differ by a port they are bound to.
    for (int i = 0; i < 6; ++i) {
        // Every other socket will be IPv4.
        if (i % 2) {
            ASSERT_NO_THROW(
                iface_mgr->openSocket(LOOPBACK, loaddr, 10000 + i)
            );
        } else {
            ASSERT_NO_THROW(
                iface_mgr->openSocket(LOOPBACK, loaddr6, 10000 + i)
            );
        }
    }

    // At the end we should have 3 IPv4 and 3 IPv6 sockets open.
    Iface* iface = iface_mgr->getIface(LOOPBACK);
    ASSERT_TRUE(iface != NULL);

    int v4_sockets_count = getOpenSocketsCount(*iface, AF_INET);
    ASSERT_EQ(3, v4_sockets_count);
    int v6_sockets_count = getOpenSocketsCount(*iface, AF_INET6);
    ASSERT_EQ(3, v6_sockets_count);

    // Let's try to close only IPv4 sockets.
    ASSERT_NO_THROW(iface_mgr->closeSockets(AF_INET));
    v4_sockets_count = getOpenSocketsCount(*iface, AF_INET);
    EXPECT_EQ(0, v4_sockets_count);
    // The IPv6 sockets should remain open.
    v6_sockets_count = getOpenSocketsCount(*iface, AF_INET6);
    EXPECT_EQ(3, v6_sockets_count);

    // Let's try to close IPv6 sockets.
    ASSERT_NO_THROW(iface_mgr->closeSockets(AF_INET6));
    v4_sockets_count = getOpenSocketsCount(*iface, AF_INET);
    EXPECT_EQ(0, v4_sockets_count);
    // They should have been closed now.
    v6_sockets_count = getOpenSocketsCount(*iface, AF_INET6);
    EXPECT_EQ(0, v6_sockets_count);
}

576
TEST_F(IfaceMgrTest, ifaceClass) {
577
    // Basic tests for Iface inner class
578

579
    Iface iface("eth5", 7);
580
    EXPECT_STREQ("eth5/7", iface.getFullName().c_str());
581
582
}

583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
// Test that the IPv4 address can be retrieved for the interface.
TEST_F(IfaceMgrTest, ifaceGetAddress) {
    Iface iface("eth0", 0);

    IOAddress addr("::1");
    // Initially, the Iface has no addresses assigned.
    EXPECT_FALSE(iface.getAddress4(addr));
    // Add some addresses with IPv4 address in the middle.
    iface.addAddress(IOAddress("fe80::3a60:77ff:fed5:cdef"));
    iface.addAddress(IOAddress("10.1.2.3"));
    iface.addAddress(IOAddress("2001:db8:1::2"));
    // The v4 address should be returned.
    EXPECT_TRUE(iface.getAddress4(addr));
    EXPECT_EQ("10.1.2.3", addr.toText());
    // Delete the IPv4 address and leave only two IPv6 addresses.
    ASSERT_NO_THROW(iface.delAddress(IOAddress("10.1.2.3")));
    // The IPv4 address should not be returned.
    EXPECT_FALSE(iface.getAddress4(addr));
    // Add a different IPv4 address at the end of the list.
    iface.addAddress(IOAddress("192.0.2.3"));
    // This new address should now be returned.
    EXPECT_TRUE(iface.getAddress4(addr));
    EXPECT_EQ("192.0.2.3", addr.toText());

}

609
610
// TODO: Implement getPlainMac() test as soon as interface detection
// is implemented.
611
612
613
TEST_F(IfaceMgrTest, getIface) {

    cout << "Interface checks. Please ignore socket binding errors." << endl;
614
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
615

616
    // Interface name, ifindex
617
618
619
620
    Iface iface1("lo1", 100);
    Iface iface2("eth9", 101);
    Iface iface3("en3", 102);
    Iface iface4("e1000g4", 103);
621
622
623
    cout << "This test assumes that there are less than 100 network interfaces"
         << " in the tested system and there are no lo1, eth9, en3, e1000g4"
         << " or wifi15 interfaces present." << endl;
624

625
    // Note: real interfaces may be detected as well
626
627
628
629
630
    ifacemgr->getIfacesLst().push_back(iface1);
    ifacemgr->getIfacesLst().push_back(iface2);
    ifacemgr->getIfacesLst().push_back(iface3);
    ifacemgr->getIfacesLst().push_back(iface4);

631
632
    cout << "There are " << ifacemgr->getIfacesLst().size()
         << " interfaces." << endl;
633
    for (IfaceMgr::IfaceCollection::iterator iface=ifacemgr->getIfacesLst().begin();
634
635
         iface != ifacemgr->getIfacesLst().end();
         ++iface) {
636
        cout << "  " << iface->getFullName() << endl;
637
638
639
    }


640
    // Check that interface can be retrieved by ifindex
641
    Iface* tmp = ifacemgr->getIface(102);
642
    ASSERT_TRUE(tmp != NULL);
643

644
    EXPECT_EQ("en3", tmp->getName());
645
    EXPECT_EQ(102, tmp->getIndex());
646

647
    // Check that interface can be retrieved by name
648
    tmp = ifacemgr->getIface("lo1");
649
    ASSERT_TRUE(tmp != NULL);
650

651
    EXPECT_EQ("lo1", tmp->getName());
652
    EXPECT_EQ(100, tmp->getIndex());
653

654
    // Check that non-existing interfaces are not returned
655
    EXPECT_EQ(static_cast<void*>(NULL), ifacemgr->getIface("wifi15") );
656
657
}

658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
TEST_F(IfaceMgrTest, clearIfaces) {
    NakedIfaceMgr ifacemgr;
    // Create a set of fake interfaces. At the same time, remove the actual
    // interfaces that have been detected by the IfaceMgr.
    ifacemgr.createIfaces();

    ASSERT_GT(ifacemgr.countIfaces(), 0);

    boost::shared_ptr<TestPktFilter> custom_packet_filter(new TestPktFilter());
    ASSERT_TRUE(custom_packet_filter);
    ASSERT_NO_THROW(ifacemgr.setPacketFilter(custom_packet_filter));

    ASSERT_NO_THROW(ifacemgr.openSockets4());

    ifacemgr.clearIfaces();

    EXPECT_EQ(0, ifacemgr.countIfaces());
}

677
TEST_F(IfaceMgrTest, receiveTimeout6) {
678
    using namespace boost::posix_time;
679
680
681
682
    std::cout << "Testing DHCPv6 packet reception timeouts."
              << " Test will block for a few seconds when waiting"
              << " for timeout to occur." << std::endl;

683
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
684
685
686
687
688
689
    // Open socket on the lo interface.
    IOAddress loAddr("::1");
    int socket1 = 0;
    ASSERT_NO_THROW(
        socket1 = ifacemgr->openSocket(LOOPBACK, loAddr, 10547)
    );
690
691
    // Socket is open if result is non-negative.
    ASSERT_GE(socket1, 0);
692
693

    // Remember when we call receive6().
694
    ptime start_time = microsec_clock::universal_time();
695
    // Call receive with timeout of 1s + 400000us = 1.4s.
696
    Pkt6Ptr pkt;
697
    ASSERT_NO_THROW(pkt = ifacemgr->receive6(1, 400000));
698
    // Remember when call to receive6() ended.
699
    ptime stop_time = microsec_clock::universal_time();
700
701
702
703
    // We did not send a packet to lo interface so we expect that
    // nothing has been received and timeout has been reached.
    ASSERT_FALSE(pkt);
    // Calculate duration of call to receive6().
704
    time_duration duration = stop_time - start_time;
705
706
707
    // We stop the clock when the call completes so it does not
    // precisely reflect the receive timeout. However the
    // uncertainity should be low enough to expect that measured
708
    // value is in the range <1.4s; 1.7s>.
709
710
    EXPECT_GE(duration.total_microseconds(),
              1400000 - TIMEOUT_TOLERANCE);
711
    EXPECT_LE(duration.total_microseconds(), 1700000);
712
713

    // Test timeout shorter than 1s.
714
    start_time = microsec_clock::universal_time();
715
    ASSERT_NO_THROW(pkt = ifacemgr->receive6(0, 500000));
716
    stop_time = microsec_clock::universal_time();
717
    ASSERT_FALSE(pkt);
718
    duration = stop_time - start_time;
719
    // Check if measured duration is within <0.5s; 0.8s>.
720
721
    EXPECT_GE(duration.total_microseconds(),
              500000 - TIMEOUT_TOLERANCE);
722
    EXPECT_LE(duration.total_microseconds(), 800000);
723
724
725
726

    // Test with invalid fractional timeout values.
    EXPECT_THROW(ifacemgr->receive6(0, 1000000), isc::BadValue);
    EXPECT_THROW(ifacemgr->receive6(1, 1000010), isc::BadValue);
727
728
729
}

TEST_F(IfaceMgrTest, receiveTimeout4) {
730
    using namespace boost::posix_time;
731
732
733
734
    std::cout << "Testing DHCPv6 packet reception timeouts."
              << " Test will block for a few seconds when waiting"
              << " for timeout to occur." << std::endl;

735
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
736
737
738
739
740
741
    // Open socket on the lo interface.
    IOAddress loAddr("127.0.0.1");
    int socket1 = 0;
    ASSERT_NO_THROW(
        socket1 = ifacemgr->openSocket(LOOPBACK, loAddr, 10067)
    );
742
743
    // Socket is open if returned value is non-negative.
    ASSERT_GE(socket1, 0);
744

745
    Pkt4Ptr pkt;
746
    // Remember when we call receive4().
747
    ptime start_time = microsec_clock::universal_time();
748
749
    // Call receive with timeout of 2s + 300000us = 2.3s.
    ASSERT_NO_THROW(pkt = ifacemgr->receive4(2, 300000));
750
    // Remember when call to receive4() ended.
751
    ptime stop_time = microsec_clock::universal_time();
752
753
754
755
    // We did not send a packet to lo interface so we expect that
    // nothing has been received and timeout has been reached.
    ASSERT_FALSE(pkt);
    // Calculate duration of call to receive4().
756
    time_duration duration = stop_time - start_time;
757
758
759
    // We stop the clock when the call completes so it does not
    // precisely reflect the receive timeout. However the
    // uncertainity should be low enough to expect that measured
760
    // value is in the range <2.3s; 2.6s>.
761
762
    EXPECT_GE(duration.total_microseconds(),
              2300000 - TIMEOUT_TOLERANCE);
763
    EXPECT_LE(duration.total_microseconds(), 2600000);
764
765

    // Test timeout shorter than 1s.
766
    start_time = microsec_clock::universal_time();
767
    ASSERT_NO_THROW(pkt = ifacemgr->receive4(0, 400000));
768
    stop_time = microsec_clock::universal_time();
769
    ASSERT_FALSE(pkt);
770
    duration = stop_time - start_time;
771
    // Check if measured duration is within <0.4s; 0.7s>.
772
773
    EXPECT_GE(duration.total_microseconds(),
              400000 - TIMEOUT_TOLERANCE);
774
    EXPECT_LE(duration.total_microseconds(), 700000);
775
776
777
778

    // Test with invalid fractional timeout values.
    EXPECT_THROW(ifacemgr->receive6(0, 1000000), isc::BadValue);
    EXPECT_THROW(ifacemgr->receive6(2, 1000005), isc::BadValue);
779
780
}

781
TEST_F(IfaceMgrTest, multipleSockets) {
782
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
783

784
    // Container for initialized socket descriptors
785
786
    std::list<uint16_t> init_sockets;

787
    // Create socket #1
788
789
790
791
    int socket1 = 0;
    ASSERT_NO_THROW(
        socket1 = ifacemgr->openSocketFromIface(LOOPBACK, PORT1, AF_INET);
    );
792
    ASSERT_GE(socket1, 0);
793
794
    init_sockets.push_back(socket1);

795
    // Create socket #2
796
797
798
799
800
    IOAddress loAddr("127.0.0.1");
    int socket2 = 0;
    ASSERT_NO_THROW(
        socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, PORT2);
    );
801
    ASSERT_GE(socket2, 0);
802
803
804
805
    init_sockets.push_back(socket2);

    // Get loopback interface. If we don't find one we are unable to run
    // this test but we don't want to fail.
806
    Iface* iface_ptr = ifacemgr->getIface(LOOPBACK);
807
808
809
810
811
812
813
    if (iface_ptr == NULL) {
        cout << "Local loopback interface not found. Skipping test. " << endl;
        return;
    }
    // Once sockets have been sucessfully opened, they are supposed to
    // be on the list. Here we start to test if all expected sockets
    // are on the list and no other (unexpected) socket is there.
814
    Iface::SocketCollection sockets = iface_ptr->getSockets();
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    int matched_sockets = 0;
    for (std::list<uint16_t>::iterator init_sockets_it =
             init_sockets.begin();
         init_sockets_it != init_sockets.end(); ++init_sockets_it) {
        // Set socket descriptors non blocking in order to be able
        // to call recv() on them without hang.
        int flags = fcntl(*init_sockets_it, F_GETFL, 0);
        ASSERT_GE(flags, 0);
        ASSERT_GE(fcntl(*init_sockets_it, F_SETFL, flags | O_NONBLOCK), 0);
        // recv() is expected to result in EWOULDBLOCK error on non-blocking
        // socket in case socket is valid but simply no data are coming in.
        char buf;
        recv(*init_sockets_it, &buf, 1, MSG_PEEK);
        EXPECT_EQ(EWOULDBLOCK, errno);
        // Apart from the ability to use the socket we want to make
        // sure that socket on the list is the one that we created.
831
        for (Iface::SocketCollection::const_iterator socket_it =
832
833
834
835
836
837
838
839
                 sockets.begin(); socket_it != sockets.end(); ++socket_it) {
            if (*init_sockets_it == socket_it->sockfd_) {
                // This socket is the one that we created.
                ++matched_sockets;
                break;
            }
        }
    }
840
    // All created sockets have been matched if this condition works.
841
842
843
844
845
846
847
    EXPECT_EQ(sockets.size(), matched_sockets);

    // closeSockets() is the other function that we want to test. It
    // is supposed to close all sockets so as we will not be able to use
    // them anymore communication.
    ifacemgr->closeSockets();

848
    // Closed sockets are supposed to be removed from the list
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
    sockets = iface_ptr->getSockets();
    ASSERT_EQ(0, sockets.size());

    // We are still in posession of socket descriptors that we created
    // on the beginning of this test. We can use them to check whether
    // closeSockets() only removed them from the list or they have been
    // really closed.
    for (std::list<uint16_t>::const_iterator init_sockets_it =
             init_sockets.begin();
         init_sockets_it != init_sockets.end(); ++init_sockets_it) {
        // recv() must result in error when using invalid socket.
        char buf;
        recv(*init_sockets_it, &buf, 1, MSG_PEEK);
        // EWOULDBLOCK would mean that socket is valid/open but
        // simply no data is received so we have to check for
        // other errors.
        EXPECT_NE(EWOULDBLOCK, errno);
    }
}

869
TEST_F(IfaceMgrTest, sockets6) {
870
871
    // Testing socket operation in a portable way is tricky
    // without interface detection implemented.
872

873
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
874

875
    IOAddress loAddr("::1");
876

877
878
    Pkt6 pkt6(DHCPV6_SOLICIT, 123);
    pkt6.setIface(LOOPBACK);
879

880
    // Bind multicast socket to port 10547
881
    int socket1 = ifacemgr->openSocket(LOOPBACK, loAddr, 10547);
882
    EXPECT_GE(socket1, 0); // socket >= 0
883

884
885
    EXPECT_EQ(socket1, ifacemgr->getSocket(pkt6));

886
    // Bind unicast socket to port 10548
887
    int socket2 = ifacemgr->openSocket(LOOPBACK, loAddr, 10548);
888
    EXPECT_GE(socket2, 0);
889

890
    // Removed code for binding socket twice to the same address/port
891
    // as it caused problems on some platforms (e.g. Mac OS X)
892

893
894
    // Close sockets here because the following tests will want to
    // open sockets on the same ports.
895
    ifacemgr->closeSockets();
896

897
898
899
900
901
902
903
904
905
906
907
908
    // Use address that is not assigned to LOOPBACK iface.
    IOAddress invalidAddr("::2");
    EXPECT_THROW(
        ifacemgr->openSocket(LOOPBACK, invalidAddr, 10547),
        SocketConfigError
    );

    // Use non-existing interface name.
    EXPECT_THROW(
        ifacemgr->openSocket("non_existing_interface", loAddr, 10548),
        BadValue
    );
909
910
911

    // Do not call closeSockets() because it is called by IfaceMgr's
    // virtual destructor.
912
913
}

914
TEST_F(IfaceMgrTest, socketsFromIface) {
915
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
916

917
    // Open v6 socket on loopback interface and bind to port
918
919
    int socket1 = 0;
    EXPECT_NO_THROW(
920
        socket1 = ifacemgr->openSocketFromIface(LOOPBACK, PORT1, AF_INET6);
921
    );
922
923
    // Socket descriptor must be non-negative integer
    EXPECT_GE(socket1, 0);
924
    close(socket1);
925

926
    // Open v4 socket on loopback interface and bind to different port
927
928
    int socket2 = 0;
    EXPECT_NO_THROW(
929
        socket2 = ifacemgr->openSocketFromIface(LOOPBACK, PORT2, AF_INET);
930
    );
931
932
    // socket descriptor must be non-negative integer
    EXPECT_GE(socket2, 0);
933
934
    close(socket2);

935
936
    // Close sockets here because the following tests will want to
    // open sockets on the same ports.
937
938
939
940
941
942
943
    ifacemgr->closeSockets();

    // Use invalid interface name.
    EXPECT_THROW(
        ifacemgr->openSocketFromIface("non_existing_interface", PORT1, AF_INET),
        BadValue
    );
944
945
946

    // Do not call closeSockets() because it is called by IfaceMgr's
    // virtual destructor.
947
948
949
}


950
TEST_F(IfaceMgrTest, socketsFromAddress) {
951
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
952

953
    // Open v6 socket on loopback interface and bind to port
954
    int socket1 = 0;
955
    IOAddress loAddr6("::1");
956
    EXPECT_NO_THROW(
957
        socket1 = ifacemgr->openSocketFromAddress(loAddr6, PORT1);
958
    );
959
960
    // socket descriptor must be non-negative integer
    EXPECT_GE(socket1, 0);
961

962
    // Open v4 socket on loopback interface and bind to different port
963
    int socket2 = 0;
964
    IOAddress loAddr("127.0.0.1");
965
    EXPECT_NO_THROW(
966
        socket2 = ifacemgr->openSocketFromAddress(loAddr, PORT2);
967
968
    );
    // socket descriptor must be positive integer
969
    EXPECT_GE(socket2, 0);
970

971
972
    // Close sockets here because the following tests will want to
    // open sockets on the same ports.
973
974
975
976
977
978
979
    ifacemgr->closeSockets();

    // Use non-existing address.
    IOAddress invalidAddr("1.2.3.4");
    EXPECT_THROW(
        ifacemgr->openSocketFromAddress(invalidAddr, PORT1), BadValue
    );
980
981
982

    // Do not call closeSockets() because it is called by IfaceMgr's
    // virtual destructor.
983
984
}

985
TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
986
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
987

988
989
990
    // Open v6 socket to connect to remote address.
    // Loopback address is the only one that we know
    // so let's treat it as remote address.
991
    int socket1 = 0;
992
    IOAddress loAddr6("::1");
993
    EXPECT_NO_THROW(
994
        socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, PORT1);
995
    );
996
    EXPECT_GE(socket1, 0);
997

998
    // Open v4 socket to connect to remote address.
999
    int socket2 = 0;
1000
    IOAddress loAddr("127.0.0.1");
1001
    EXPECT_NO_THROW(
1002
        socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, PORT2);
1003
    );
1004
    EXPECT_GE(socket2, 0);
1005

1006
1007
    // Close sockets here because the following tests will want to
    // open sockets on the same ports.
1008
    ifacemgr->closeSockets();
1009

1010
1011
    // There used to be a check here that verified the ability to open
    // suitable socket for sending broadcast request. However,
1012
1013
    // there is no guarantee for such test to work on all systems
    // because some systems may have no broadcast capable interfaces at all.
1014
    // Thus, this check has been removed.
1015
1016
1017

    // Do not call closeSockets() because it is called by IfaceMgr's
    // virtual destructor.
1018
1019
}

1020
1021
// TODO: disabled due to other naming on various systems
// (lo in Linux, lo0 in BSD systems)
1022
TEST_F(IfaceMgrTest, DISABLED_sockets6Mcast) {
1023
1024
1025
    // testing socket operation in a portable way is tricky
    // without interface detection implemented

1026
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
1027
1028
1029
1030
1031

    IOAddress loAddr("::1");
    IOAddress mcastAddr("ff02::1:2");

    // bind multicast socket to port 10547
1032
    int socket1 = ifacemgr->openSocket(LOOPBACK, mcastAddr, 10547);
1033
    EXPECT_GE(socket1, 0); // socket > 0
1034
1035
1036

    // expect success. This address/port is already bound, but
    // we are using SO_REUSEADDR, so we can bind it twice
1037
    int socket2 = ifacemgr->openSocket(LOOPBACK, mcastAddr, 10547);
1038
    EXPECT_GE(socket2, 0);
1039

1040
1041
1042
1043
    // there's no good way to test negative case here.
    // we would need non-multicast interface. We will be able
    // to iterate thru available interfaces and check if there
    // are interfaces without multicast-capable flag.
1044
1045
1046
1047
1048

    close(socket1);
    close(socket2);
}

1049
TEST_F(IfaceMgrTest, sendReceive6) {
1050

1051
1052
1053
    // testing socket operation in a portable way is tricky
    // without interface detection implemented

1054
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
1055
1056

    // let's assume that every supported OS have lo interface
1057
    IOAddress loAddr("::1");
1058
1059
1060
1061
1062
    int socket1 = 0, socket2 = 0;
    EXPECT_NO_THROW(
        socket1 = ifacemgr->openSocket(LOOPBACK, loAddr, 10547);
        socket2 = ifacemgr->openSocket(LOOPBACK, loAddr, 10546);
    );
1063

1064
1065
    EXPECT_GE(socket1, 0);
    EXPECT_GE(socket2, 0);
1066
1067
1068


    // prepare dummy payload
1069
    uint8_t data[128];
1070
    for (int i = 0; i < 128; i++) {
1071
        data[i] = i;
1072
    }
1073
    Pkt6Ptr sendPkt = Pkt6Ptr(new Pkt6(data, 128));
1074

1075
    sendPkt->repack();
1076

1077
1078
1079
1080
1081
1082
    sendPkt->setRemotePort(10547);
    sendPkt->setRemoteAddr(IOAddress("::1"));
    sendPkt->setIndex(1);
    sendPkt->setIface(LOOPBACK);

    Pkt6Ptr rcvPkt;
1083
1084
1085

    EXPECT_EQ(true, ifacemgr->send(sendPkt));

1086
    rcvPkt = ifacemgr->receive6(10);
1087

1088
    ASSERT_TRUE(rcvPkt); // received our own packet
1089
1090

    // let's check that we received what was sent
1091
1092
1093
    ASSERT_EQ(sendPkt->data_.size(), rcvPkt->data_.size());
    EXPECT_EQ(0, memcmp(&sendPkt->data_[0], &rcvPkt->data_[0],
                        rcvPkt->data_.size()));
1094

1095
    EXPECT_EQ(sendPkt->getRemoteAddr(), rcvPkt->getRemoteAddr());
1096
1097
1098

    // since we opened 2 sockets on the same interface and none of them is multicast,
    // none is preferred over the other for sending data, so we really should not
1099
    // assume the one or the other will always be chosen for sending data. Therefore
1100
    // we should accept both values as source ports.
1101
    EXPECT_TRUE((rcvPkt->getRemotePort() == 10546) || (rcvPkt->getRemotePort() == 10547));
1102
1103
}

1104
1105
1106
1107
1108
TEST_F(IfaceMgrTest, sendReceive4) {

    // testing socket operation in a portable way is tricky
    // without interface detection implemented

1109
    scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
1110
1111
1112

    // let's assume that every supported OS have lo interface
    IOAddress loAddr("127.0.0.1");
1113
    int socket1 = 0;
1114
1115
1116
1117
    EXPECT_NO_THROW(
        socket1 = ifacemgr->openSocket(LOOPBACK, loAddr, DHCP4_SERVER_PORT + 10000);
    );

1118
1119
    EXPECT_GE(socket1, 0);

1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
    boost::shared_ptr<Pkt4> sendPkt(new Pkt4(DHCPDISCOVER, 1234) );

    sendPkt->setLocalAddr(IOAddress("127.0.0.1"));

    sendPkt->setLocalPort(DHCP4_SERVER_PORT + 10000 + 1);
    sendPkt->setRemotePort(DHCP4_SERVER_PORT + 10000);
    sendPkt->setRemoteAddr(IOAddress("127.0.0.1"));
    sendPkt->setIndex(1);
    sendPkt->setIface(string(LOOPBACK));
    sendPkt->setHops(6);
    sendPkt->setSecs(42);
    sendPkt->setCiaddr(IOAddress("192.0.2.1"));
    sendPkt->setSiaddr(IOAddress("192.0.2.2"));
    sendPkt->setYiaddr(IOAddress("192.0.2.3"));
    sendPkt->setGiaddr(IOAddress("192.0.2.4"));

1136
1137
1138
    // Unpack() now checks if mandatory DHCP_MESSAGE_TYPE is present.
    // Workarounds (creating DHCP Message Type Option by hand) are no longer
    // needed as setDhcpType() is called in constructor.
1139

1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
    uint8_t sname[] = "That's just a string that will act as SNAME";
    sendPkt->setSname(sname, strlen((const char*)sname));
    uint8_t file[] = "/another/string/that/acts/as/a/file_name.txt";
    sendPkt->setFile(file, strlen((const char*)file));

    ASSERT_NO_THROW(
        sendPkt->pack();
    );

    boost::shared_ptr<Pkt4> rcvPkt;

1151
    EXPECT_NO_THROW(ifacemgr->send(sendPkt));
1152

1153
    ASSERT_NO_THROW(rcvPkt = ifacemgr->receive4(10));
1154
    ASSERT_TRUE(rcvPkt); // received our own packet
1155
1156
1157
1158
1159
1160
1161
1162

    ASSERT_NO_THROW(
        rcvPkt->unpack();
    );

    // let's check that we received what was sent
    EXPECT_EQ(sendPkt->len(), rcvPkt->len());

1163
    EXPECT_EQ(</