blob: ffb0d5d828c10571b9e1ee99265a86b396552071 [file] [log] [blame]
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -07001#include "mock_syscall.hpp"
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07002#include "neighbor.hpp"
3#include "util.hpp"
4
5#include <arpa/inet.h>
6#include <linux/netlink.h>
7#include <linux/rtnetlink.h>
8#include <net/ethernet.h>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07009
10#include <cstring>
11#include <stdexcept>
12#include <string>
13#include <system_error>
14#include <vector>
15
16#include <gtest/gtest.h>
17
18namespace phosphor
19{
20namespace network
21{
22namespace detail
23{
24
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070025constexpr auto ifStr = "eth0";
26constexpr auto ifIdx = 1;
27
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070028TEST(ParseNeighbor, NotNeighborType)
29{
30 nlmsghdr hdr{};
31 hdr.nlmsg_type = RTM_NEWLINK;
32
33 std::vector<NeighborInfo> neighbors;
34 EXPECT_THROW(parseNeighbor(hdr, "", neighbors), std::runtime_error);
35 EXPECT_EQ(0, neighbors.size());
36}
37
38TEST(ParseNeighbor, SmallMsg)
39{
40 nlmsghdr hdr{};
41 hdr.nlmsg_type = RTM_NEWNEIGH;
42 std::string data = "1";
43
44 std::vector<NeighborInfo> neighbors;
45 EXPECT_THROW(parseNeighbor(hdr, data, neighbors), std::runtime_error);
46 EXPECT_EQ(0, neighbors.size());
47}
48
49TEST(ParseNeighbor, BadIf)
50{
51 nlmsghdr hdr{};
52 hdr.nlmsg_type = RTM_NEWNEIGH;
53 ndmsg msg{};
54 std::string data;
55 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
56
57 std::vector<NeighborInfo> neighbors;
58 EXPECT_THROW(parseNeighbor(hdr, data, neighbors), std::system_error);
59 EXPECT_EQ(0, neighbors.size());
60}
61
62TEST(ParseNeighbor, NoAttrs)
63{
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070064 mock_addIF(ifStr, ifIdx);
65
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070066 nlmsghdr hdr{};
67 hdr.nlmsg_type = RTM_NEWNEIGH;
68 ndmsg msg{};
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070069 msg.ndm_ifindex = ifIdx;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070070 ASSERT_NE(0, msg.ndm_ifindex);
71 std::string data;
72 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
73
74 std::vector<NeighborInfo> neighbors;
75 EXPECT_THROW(parseNeighbor(hdr, data, neighbors), std::runtime_error);
76 EXPECT_EQ(0, neighbors.size());
77}
78
79TEST(ParseNeighbor, NoAddress)
80{
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070081 mock_addIF(ifStr, ifIdx);
82
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070083 nlmsghdr hdr{};
84 hdr.nlmsg_type = RTM_NEWNEIGH;
85 ndmsg msg{};
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -070086 msg.ndm_ifindex = ifIdx;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070087 ASSERT_NE(0, msg.ndm_ifindex);
88 ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
89 rtattr lladdr{};
90 lladdr.rta_len = RTA_LENGTH(sizeof(mac));
91 lladdr.rta_type = NDA_LLADDR;
92 char lladdrbuf[RTA_ALIGN(lladdr.rta_len)];
93 std::memset(lladdrbuf, '\0', sizeof(lladdrbuf));
94 std::memcpy(lladdrbuf, &lladdr, sizeof(lladdr));
95 std::memcpy(RTA_DATA(lladdrbuf), &mac, sizeof(mac));
96 std::string data;
97 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
98 data.append(reinterpret_cast<char*>(&lladdrbuf), sizeof(lladdrbuf));
99
100 std::vector<NeighborInfo> neighbors;
101 EXPECT_THROW(parseNeighbor(hdr, data, neighbors), std::runtime_error);
102 EXPECT_EQ(0, neighbors.size());
103}
104
105TEST(ParseNeighbor, NoMAC)
106{
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -0700107 mock_addIF(ifStr, ifIdx);
108
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700109 nlmsghdr hdr{};
110 hdr.nlmsg_type = RTM_NEWNEIGH;
111 ndmsg msg{};
112 msg.ndm_family = AF_INET;
113 msg.ndm_state = NUD_PERMANENT;
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -0700114 msg.ndm_ifindex = ifIdx;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700115 ASSERT_NE(0, msg.ndm_ifindex);
116 in_addr addr;
117 ASSERT_EQ(1, inet_pton(msg.ndm_family, "192.168.10.1", &addr));
118 rtattr dst{};
119 dst.rta_len = RTA_LENGTH(sizeof(addr));
120 dst.rta_type = NDA_DST;
121 char dstbuf[RTA_ALIGN(dst.rta_len)];
122 std::memset(dstbuf, '\0', sizeof(dstbuf));
123 std::memcpy(dstbuf, &dst, sizeof(dst));
124 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
125 std::string data;
126 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
127 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
128
129 std::vector<NeighborInfo> neighbors;
130 parseNeighbor(hdr, data, neighbors);
131 EXPECT_EQ(1, neighbors.size());
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -0700132 EXPECT_EQ(ifStr, neighbors[0].interface);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700133 EXPECT_TRUE(neighbors[0].permanent);
134 EXPECT_FALSE(neighbors[0].mac);
135 EXPECT_TRUE(equal(addr, std::get<in_addr>(neighbors[0].address)));
136}
137
138TEST(ParseNeighbor, Full)
139{
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -0700140 mock_addIF(ifStr, ifIdx);
141
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700142 nlmsghdr hdr{};
143 hdr.nlmsg_type = RTM_NEWNEIGH;
144 ndmsg msg{};
145 msg.ndm_family = AF_INET6;
146 msg.ndm_state = NUD_NOARP;
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -0700147 msg.ndm_ifindex = ifIdx;
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700148 ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
149 rtattr lladdr{};
150 lladdr.rta_len = RTA_LENGTH(sizeof(mac));
151 lladdr.rta_type = NDA_LLADDR;
152 char lladdrbuf[RTA_ALIGN(lladdr.rta_len)];
153 std::memset(lladdrbuf, '\0', sizeof(lladdrbuf));
154 std::memcpy(lladdrbuf, &lladdr, sizeof(lladdr));
155 std::memcpy(RTA_DATA(lladdrbuf), &mac, sizeof(mac));
156 in6_addr addr;
157 ASSERT_EQ(1, inet_pton(msg.ndm_family, "fd00::1", &addr));
158 rtattr dst{};
159 dst.rta_len = RTA_LENGTH(sizeof(addr));
160 dst.rta_type = NDA_DST;
161 char dstbuf[RTA_ALIGN(dst.rta_len)];
162 std::memset(dstbuf, '\0', sizeof(dstbuf));
163 std::memcpy(dstbuf, &dst, sizeof(dst));
164 std::memcpy(RTA_DATA(dstbuf), &addr, sizeof(addr));
165 std::string data;
166 data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
167 data.append(reinterpret_cast<char*>(&lladdrbuf), sizeof(lladdrbuf));
168 data.append(reinterpret_cast<char*>(&dstbuf), sizeof(dstbuf));
169
170 std::vector<NeighborInfo> neighbors;
171 parseNeighbor(hdr, data, neighbors);
172 EXPECT_EQ(1, neighbors.size());
William A. Kennington IIIebb1ad02019-04-21 18:02:49 -0700173 EXPECT_EQ(ifStr, neighbors[0].interface);
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700174 EXPECT_FALSE(neighbors[0].permanent);
175 EXPECT_TRUE(neighbors[0].mac);
William A. Kennington III6ca08d82019-04-20 16:04:18 -0700176 EXPECT_TRUE(equal(mac, *neighbors[0].mac));
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700177 EXPECT_TRUE(equal(addr, std::get<in6_addr>(neighbors[0].address)));
178}
179
180} // namespace detail
181} // namespace network
182} // namespace phosphor